Skip to content

Commit cde789e

Browse files
committed
KVM: TDX: Set per-VM shadow_mmio_value to 0
JIRA: https://issues.redhat.com/browse/RHEL-15711 Upstream status: https://git.kernel.org/pub/scm/virt/kvm/kvm.git Set per-VM shadow_mmio_value to 0 for TDX. With enable_mmio_caching on, KVM installs MMIO SPTEs for TDs. To correctly configure MMIO SPTEs, TDX requires the per-VM shadow_mmio_value to be set to 0. This is necessary to override the default value of the suppress VE bit in the SPTE, which is 1, and to ensure value 0 in RWX bits. For MMIO SPTE, the spte value changes as follows: 1. initial value (suppress VE bit is set) 2. Guest issues MMIO and triggers EPT violation 3. KVM updates SPTE value to MMIO value (suppress VE bit is cleared) 4. Guest MMIO resumes. It triggers VE exception in guest TD 5. Guest VE handler issues TDG.VP.VMCALL<MMIO> 6. KVM handles MMIO 7. Guest VE handler resumes its execution after MMIO instruction Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> Co-developed-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Co-developed-by: Yan Zhao <yan.y.zhao@intel.com> Signed-off-by: Yan Zhao <yan.y.zhao@intel.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20241112073743.22214-1-yan.y.zhao@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> (cherry picked from commit 7d10ffb) Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 993461a commit cde789e

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

arch/x86/kvm/mmu/spte.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access)
7474
u64 spte = generation_mmio_spte_mask(gen);
7575
u64 gpa = gfn << PAGE_SHIFT;
7676

77-
WARN_ON_ONCE(!vcpu->kvm->arch.shadow_mmio_value);
78-
7977
access &= shadow_mmio_access_mask;
8078
spte |= vcpu->kvm->arch.shadow_mmio_value | access;
8179
spte |= gpa | shadow_nonpresent_or_rsvd_mask;

arch/x86/kvm/vmx/tdx.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "x86_ops.h"
99
#include "lapic.h"
1010
#include "tdx.h"
11+
#include "mmu/spte.h"
1112

1213
#pragma GCC poison to_vmx
1314

@@ -410,6 +411,19 @@ int tdx_vm_init(struct kvm *kvm)
410411
kvm->arch.has_protected_state = true;
411412
kvm->arch.has_private_mem = true;
412413

414+
/*
415+
* Because guest TD is protected, VMM can't parse the instruction in TD.
416+
* Instead, guest uses MMIO hypercall. For unmodified device driver,
417+
* #VE needs to be injected for MMIO and #VE handler in TD converts MMIO
418+
* instruction into MMIO hypercall.
419+
*
420+
* SPTE value for MMIO needs to be setup so that #VE is injected into
421+
* TD instead of triggering EPT MISCONFIG.
422+
* - RWX=0 so that EPT violation is triggered.
423+
* - suppress #VE bit is cleared to inject #VE.
424+
*/
425+
kvm_mmu_set_mmio_spte_value(kvm, 0);
426+
413427
/*
414428
* TDX has its own limit of maximum vCPUs it can support for all
415429
* TDX guests in addition to KVM_MAX_VCPUS. TDX module reports

0 commit comments

Comments
 (0)