KVM: TDX: Require TDP MMU, mmio caching and EPT A/D bits for TDX
authorIsaku Yamahata <isaku.yamahata@intel.com>
Tue, 12 Nov 2024 07:37:20 +0000 (15:37 +0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 14 Mar 2025 18:20:52 +0000 (14:20 -0400)
Disable TDX support when TDP MMU or mmio caching or EPT A/D bits aren't
supported.

As TDP MMU is becoming main stream than the legacy MMU, the legacy MMU
support for TDX isn't implemented.

TDX requires KVM mmio caching. Without mmio caching, KVM will go to MMIO
emulation without installing SPTEs for MMIOs. However, TDX guest is
protected and KVM would meet errors when trying to emulate MMIOs for TDX
guest during instruction decoding. So, TDX guest relies on SPTEs being
installed for MMIOs, which are with no RWX bits and with VE suppress bit
unset, to inject VE to TDX guest. The TDX guest would then issue TDVMCALL
in the VE handler to perform instruction decoding and have host do MMIO
emulation.

TDX also relies on EPT A/D bits as EPT A/D bits have been supported in all
CPUs since Haswell. Relying on it can avoid RWX bits being masked out in
the mirror page table for prefaulted entries.

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>
Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
---
Requested by Sean at [1].
[1] https://lore.kernel.org/kvm/Zva4aORxE9ljlMNe@google.com/
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/vmx/main.c
arch/x86/kvm/vmx/tdx.c

index ec086f831e69cb8bae0812392aaa8ac918578972..af6c11995cec62a51a86ed1977b75ed9cc8858b5 100644 (file)
@@ -110,6 +110,7 @@ static bool __ro_after_init tdp_mmu_allowed;
 #ifdef CONFIG_X86_64
 bool __read_mostly tdp_mmu_enabled = true;
 module_param_named(tdp_mmu, tdp_mmu_enabled, bool, 0444);
+EXPORT_SYMBOL_GPL(tdp_mmu_enabled);
 #endif
 
 static int max_huge_page_level __read_mostly;
index 8ed08c53c02f68f089200cb75503a960fbdfbeea..a4cb3d6b2986b210aada259aa1d8a27b4289f52a 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "x86_ops.h"
 #include "vmx.h"
+#include "mmu.h"
 #include "nested.h"
 #include "pmu.h"
 #include "posted_intr.h"
index 5a641daf13d41e2adc8f2aa06a8fd1dc7621f888..78ed554203d7ad91a5d59875d83fa53013f2aa19 100644 (file)
@@ -1534,6 +1534,16 @@ int __init tdx_bringup(void)
        if (!enable_tdx)
                return 0;
 
+       if (!enable_ept) {
+               pr_err("EPT is required for TDX\n");
+               goto success_disable_tdx;
+       }
+
+       if (!tdp_mmu_enabled || !enable_mmio_caching || !enable_ept_ad_bits) {
+               pr_err("TDP MMU and MMIO caching and EPT A/D bit is required for TDX\n");
+               goto success_disable_tdx;
+       }
+
        if (!cpu_feature_enabled(X86_FEATURE_MOVDIR64B)) {
                pr_err("tdx: MOVDIR64B is required for TDX\n");
                goto success_disable_tdx;