Message ID | 20240904030751.117579-13-rick.p.edgecombe@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | TDX MMU Part 2 | expand |
On 9/4/24 05:07, Rick Edgecombe wrote: > diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c > index 46a26be0245b..4ab6d2a87032 100644 > --- a/arch/x86/kvm/mmu/spte.c > +++ b/arch/x86/kvm/mmu/spte.c > @@ -94,8 +94,6 @@ u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access) > u64 spte = generation_mmio_spte_mask(gen); > u64 gpa = gfn << PAGE_SHIFT; > > - WARN_ON_ONCE(!vcpu->kvm->arch.shadow_mmio_value); > - > access &= shadow_mmio_access_mask; > spte |= vcpu->kvm->arch.shadow_mmio_value | access; > spte |= gpa | shadow_nonpresent_or_rsvd_mask; > diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c > index 0c08062ef99f..9da71782660f 100644 > --- a/arch/x86/kvm/vmx/tdx.c > +++ b/arch/x86/kvm/vmx/tdx.c > @@ -6,7 +6,7 @@ > #include "mmu.h" > #include "tdx.h" > #include "tdx_ops.h" > - > +#include "mmu/spte.h" > > #undef pr_fmt > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > @@ -344,6 +344,19 @@ int tdx_vm_init(struct kvm *kvm) > { > kvm->arch.has_private_mem = true; > > + /* > + * Because guest TD is protected, VMM can't parse the instruction in TD. > + * Instead, guest uses MMIO hypercall. For unmodified device driver, > + * #VE needs to be injected for MMIO and #VE handler in TD converts MMIO > + * instruction into MMIO hypercall. > + * > + * SPTE value for MMIO needs to be setup so that #VE is injected into > + * TD instead of triggering EPT MISCONFIG. > + * - RWX=0 so that EPT violation is triggered. > + * - suppress #VE bit is cleared to inject #VE. > + */ > + kvm_mmu_set_mmio_spte_value(kvm, 0); > + > /* > * This function initializes only KVM software construct. It doesn't > * initialize TDX stuff, e.g. TDCS, TDR, TDCX, HKID etc. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index 46a26be0245b..4ab6d2a87032 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -94,8 +94,6 @@ u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access) u64 spte = generation_mmio_spte_mask(gen); u64 gpa = gfn << PAGE_SHIFT; - WARN_ON_ONCE(!vcpu->kvm->arch.shadow_mmio_value); - access &= shadow_mmio_access_mask; spte |= vcpu->kvm->arch.shadow_mmio_value | access; spte |= gpa | shadow_nonpresent_or_rsvd_mask; diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 0c08062ef99f..9da71782660f 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -6,7 +6,7 @@ #include "mmu.h" #include "tdx.h" #include "tdx_ops.h" - +#include "mmu/spte.h" #undef pr_fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -344,6 +344,19 @@ int tdx_vm_init(struct kvm *kvm) { kvm->arch.has_private_mem = true; + /* + * Because guest TD is protected, VMM can't parse the instruction in TD. + * Instead, guest uses MMIO hypercall. For unmodified device driver, + * #VE needs to be injected for MMIO and #VE handler in TD converts MMIO + * instruction into MMIO hypercall. + * + * SPTE value for MMIO needs to be setup so that #VE is injected into + * TD instead of triggering EPT MISCONFIG. + * - RWX=0 so that EPT violation is triggered. + * - suppress #VE bit is cleared to inject #VE. + */ + kvm_mmu_set_mmio_spte_value(kvm, 0); + /* * This function initializes only KVM software construct. It doesn't * initialize TDX stuff, e.g. TDCS, TDR, TDCX, HKID etc.