On Thu, 2022-05-05 at 11:14 -0700, isaku.yamahata@xxxxxxxxx wrote: > From: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx> > > TDX repurposes one GPA bits (51 bit or 47 bit based on configuration) to > indicate the GPA is private(if cleared) or shared (if set) with VMM. If > GPA.shared is set, GPA is converted existing conventional EPT pointed by > EPTP. If GPA.shared bit is cleared, GPA is converted by Secure-EPT(S-EPT) > TDX module manages. VMM has to issue SEAM call to TDX module to operate on > S-EPT. e.g. populating/zapping guest page or shadow page by TDH.PAGE.{ADD, > REMOVE} for guest page, TDH.PAGE.SEPT.{ADD, REMOVE} S-EPT etc. > > Several hooks needs to be added to KVM MMU to support TDX. Add a function > to check if KVM MMU is running for TDX and several functions for address > conversation between private-GPA and shared-GPA. > > Signed-off-by: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> > --- > arch/x86/include/asm/kvm_host.h | 2 ++ > arch/x86/kvm/mmu.h | 32 ++++++++++++++++++++++++++++++++ > arch/x86/kvm/mmu/mmu.c | 6 ++++-- > 3 files changed, 38 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 60a97ae55972..88fd3fd3e1a0 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -1251,7 +1251,9 @@ struct kvm_arch { > */ > u32 max_vcpu_ids; > > +#ifdef CONFIG_KVM_MMU_PRIVATE > gfn_t gfn_shared_mask; > +#endif > }; > > struct kvm_vm_stat { > diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h > index 7e258cc94152..3647035a147e 100644 > --- a/arch/x86/kvm/mmu.h > +++ b/arch/x86/kvm/mmu.h > @@ -373,4 +373,36 @@ static inline gpa_t kvm_translate_gpa(struct kvm_vcpu *vcpu, > return gpa; > return translate_nested_gpa(vcpu, gpa, access, exception); > } > + > +static inline gfn_t kvm_gfn_shared_mask(const struct kvm *kvm) > +{ > +#ifdef CONFIG_KVM_MMU_PRIVATE > + return kvm->arch.gfn_shared_mask; > +#else > + return 0; > +#endif > +} > + > +static inline gfn_t kvm_gfn_shared(const struct kvm *kvm, gfn_t gfn) > +{ > + return gfn | kvm_gfn_shared_mask(kvm); > +} > + > +static inline gfn_t kvm_gfn_private(const struct kvm *kvm, gfn_t gfn) > +{ > + return gfn & ~kvm_gfn_shared_mask(kvm); > +} > + > +static inline gpa_t kvm_gpa_private(const struct kvm *kvm, gpa_t gpa) > +{ > + return gpa & ~gfn_to_gpa(kvm_gfn_shared_mask(kvm)); > +} > + > +static inline bool kvm_is_private_gpa(const struct kvm *kvm, gpa_t gpa) > +{ > + gfn_t mask = kvm_gfn_shared_mask(kvm); > + > + return mask && !(gpa_to_gfn(gpa) & mask); > +} > + > #endif > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index 909372762363..d1c37295bb6e 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -264,8 +264,10 @@ static void kvm_flush_remote_tlbs_with_range(struct kvm *kvm, > { > int ret = -ENOTSUPP; > > - if (range && kvm_x86_ops.tlb_remote_flush_with_range) > + if (range && kvm_available_flush_tlb_with_range()) { > + /* Callback should flush both private GFN and shared GFN. */ > ret = static_call(kvm_x86_tlb_remote_flush_with_range)(kvm, range); > + } ?? > > if (ret) > kvm_flush_remote_tlbs(kvm); > @@ -4048,7 +4050,7 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault > unsigned long mmu_seq; > int r; > > - fault->gfn = fault->addr >> PAGE_SHIFT; > + fault->gfn = gpa_to_gfn(fault->addr) & ~kvm_gfn_shared_mask(vcpu->kvm); > fault->slot = kvm_vcpu_gfn_to_memslot(vcpu, fault->gfn); > > if (page_fault_handle_page_track(vcpu, fault)) As I said in previous version, this above change alone is broken: https://lore.kernel.org/lkml/cover.1646422845.git.isaku.yamahata@xxxxxxxxx/T/#mcd5c235e3577f5129810f3183f151a1c5f63466e Why cannot this patch be merged to other patch(es) which truly adds private/shared mapping support? Or did I get something wrong? -- Thanks, -Kai