[PATCH 4/4] KVM: TDX: Reject KVM_TDX_INIT_VM if indexed CPUID functions don't match
From: Sean Christopherson
Date: Fri Oct 16 2026 - 10:41:34 EST
Reject KVM_TDX_INIT_VM if userspace doesn't configure the canonical CPUID
entries correctly with respect to KVM_CPUID_FLAG_SIGNIFCANT_INDEX to fix a
bug where userspace could bypass the TSX and WAITPKG checks by simply not
marking a CPUID.0x7 entry as being indexed. This also sets the stage for
more in-depth validation of the incoming CPUID configuration.
This is obviously an ABI change and diverges from KVM's general approach of
"let userspace do what it wants". In practice, no "real" VMM that supports
TDX misconfigures a TD's CPUID entries in this way, i.e. the probability of
actually breaking userspace is basically nil. And unlike normal VMs, where
KVM has full control and thus can deal with bizarre CPUID input without too
much fuss, TDX VMs require extra care due to the TDX Module also reacting
to the CPUID configuration, i.e. KVM_TDX_INIT_VM needs to be more strict
than KVM_SET_CPUID{,2} to avoid creating potentially dangerous-to-the-host
setups.
Opportunistically rename the helper to make it more obvious that it's
checking if the passed in @entry is unsupported, as opposed to returning a
set of unsupported entries or something.
Fixes: 6d415778f106 ("KVM: TDX: Disable support for TSX and WAITPKG")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Closes: https://lore.kernel.org/kvm/20260604024927.E22311F00893@xxxxxxxxxxxxxxx
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/kvm/vmx/tdx.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 75a86d64892a..7e0d81066420 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -151,8 +151,12 @@ static void tdx_clear_unsupported_cpuid(struct kvm_cpuid_entry2 *entry)
clear_waitpkg(entry);
}
-static bool tdx_unsupported_cpuid(const struct kvm_cpuid_entry2 *entry)
+static bool tdx_is_unsupported_cpuid_entry(const struct kvm_cpuid_entry2 *entry)
{
+ if (cpuid_function_is_indexed(entry->function) !=
+ !!(entry->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX))
+ return true;
+
return has_tsx(entry) || has_waitpkg(entry);
}
@@ -2386,7 +2390,7 @@ static int setup_tdparams_cpuids(struct kvm_cpuid2 *cpuid,
if (!entry)
continue;
- if (tdx_unsupported_cpuid(entry))
+ if (tdx_is_unsupported_cpuid_entry(entry))
return -EINVAL;
copy_cnt++;
--
2.56.0.176.g3575e65682-goog
--eT79xhp2T0neg3Wb--