On 16/05/2024 11:38 am, Edgecombe, Rick P wrote:
On Thu, 2024-05-16 at 11:31 +1200, Huang, Kai wrote:
On 16/05/2024 11:21 am, Edgecombe, Rick P wrote:
On Thu, 2024-05-16 at 10:34 +1200, Huang, Kai wrote:
On 15/05/2024 12:59 pm, Rick Edgecombe wrote:
From: Isaku Yamahata <isaku.yamahata@xxxxxxxxx>
Introduce a "gfn_shared_mask" field in the kvm_arch structure to record
GPA
shared bit and provide address conversion helpers for TDX shared bit of
GPA.
TDX designates a specific GPA bit as the shared bit, which can be either
bit 51 or bit 47 based on configuration.
This GPA shared bit indicates whether the corresponding physical page is
shared (if shared bit set) or private (if shared bit cleared).
- GPAs with shared bit set will be mapped by VMM into conventional EPT,
which is pointed by shared EPTP in TDVMCS, resides in host VMM
memory
and is managed by VMM.
- GPAs with shared bit cleared will be mapped by VMM firstly into a
mirrored EPT, which resides in host VMM memory. Changes of the
mirrored
EPT are then propagated into a private EPT, which resides outside
of
host
VMM memory and is managed by TDX module.
Add the "gfn_shared_mask" field to the kvm_arch structure for each VM
with
a default value of 0. It will be set to the position of the GPA shared
bit
in GFN through TD specific initialization code.
Provide helpers to utilize the gfn_shared_mask to determine whether a
GPA
is shared or private, retrieve the GPA shared bit value, and
insert/strip
shared bit to/from a GPA.
I am seriously thinking whether we should just abandon this whole
kvm_gfn_shared_mask() thing.
We already have enough mechanisms around private memory and the mapping
of it:
1) Xarray to query whether a given GFN is private or shared;
2) fault->is_private to indicate whether a faulting address is private
or shared;
3) sp->is_private to indicate whether a "page table" is only for private
mapping;
You mean drop the helpers, or the struct kvm member? I think we still need
the
shared bit position stored somewhere. memslots, Xarray, etc need to operate
on
the GFN without the shared it.
The struct member, and the whole thing. The shared bit is only included
in the faulting address, and we can strip that away upon
handle_ept_violation().
One thing I can think of is we still need to append the shared bit to
the actual GFN when we setup the shared page table mapping. For that I
am thinking whether we can do in TDX specific code.
Anyway, I don't think the 'gfn_shared_mask' is necessarily good at this
stage.
Sorry, still not clear. We need to strip the bit away, so we need to know what
bit it is. The proposal is to not remember it on struct kvm, so where do we get
it?
The TDX specific code can get it when TDX guest is created.
Actually, we used to allow it to be selected (via GPAW), but now we could
determine it based on EPT level and MAXPA. So we could possibly recalculate it
in some helper...
But it seems you are suggesting to do away with the concept of knowing what the
shared bit is.
What I am suggesting is essentially to replace this
kvm_gfn_shared_mask() with some kvm_x86_ops callback (which can just
return the shared bit), assuming the common code somehow still need it
(e.g., setting up the SPTE for shared mapping, which must include the
shared bit to the GPA).
The advantage of this we can get rid of the concept of 'gfn_shared_mask'
in the MMU common code. All GFNs referenced in the common code is the
actual GFN (w/o the shared bit).