From: Binbin Wu <binbin.wu@linux.intel.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: seanjc@google.com, pbonzini@redhat.com,
dave.hansen@linux.intel.com, andrew.cooper3@citrix.com,
nik.borisov@suse.com, kas@kernel.org, rick.p.edgecombe@intel.com,
xiaoyao.li@intel.com, chao.gao@intel.com,
binbin.wu@linux.intel.com
Subject: [PATCH v3 4/4] KVM: TDX: Validate userspace CPUID input for KVM_TDX_INIT_VM
Date: Thu, 27 Aug 2026 11:18:37 +0800 [thread overview]
Message-ID: <20260827031837.2863609-5-binbin.wu@linux.intel.com> (raw)
In-Reply-To: <20260827031837.2863609-1-binbin.wu@linux.intel.com>
Validate the CPUID configuration provided by userspace through
KVM_TDX_INIT_VM against KVM's TDX allowlist, and drop the hardcoded
denylist based check.
The TDX module lets the VMM configure certain CPUID features for a TD at
initialization time, but KVM must strictly govern which of them userspace
can actually enable, otherwise a host state clobbering feature could be
enabled behind KVM's back. The existing check only rejects TSX and
WAITPKG, i.e. it is not fail-safe, as any bit that a future TDX module
makes configurable would be accepted even if KVM has no idea about the
feature.
Add tdx_has_unsupported_cfg_cpuid_bit() and reject KVM_TDX_INIT_VM if
userspace sets any bit outside the mask returned by
tdx_get_allowed_cfg_cpuid_mask(). There is no need to first mask the
userspace input with the bits the TDX module reports as directly
configurable, as anything outside that set is rejected by the TDX module
itself.
Also reject CPUID entries whose index differs from the value expected by
the TDX module, as kvm_find_cpuid_entry2() ignores the index when
KVM_CPUID_FLAG_SIGNIFCANT_INDEX is cleared, and so a mismatching entry
could otherwise be applied to the wrong subleaf.
Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com>
---
v3:
- Check CPUID entry index mismatch b/t userspace input and TDX sysinfo
configuration. (Sashiko)
- No need to mask the userspace input with TDX module reported directly
configurable bits first, since the userspace input should be subset of
directly configurable bits. Otherwise, the input will be rejected by
the TDX module.
---
arch/x86/kvm/vmx/tdx.c | 41 +++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index e8951353de73..12dea8775fd4 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -269,25 +269,6 @@ static u32 tdx_set_guest_phys_addr_bits(const u32 eax, int addr_bits)
return (eax & ~GENMASK(23, 16)) | (addr_bits & 0xff) << 16;
}
-#define TDX_FEATURE_TSX (__feature_bit(X86_FEATURE_HLE) | __feature_bit(X86_FEATURE_RTM))
-
-static bool has_tsx(const struct kvm_cpuid_entry2 *entry)
-{
- return entry->function == 7 && entry->index == 0 &&
- (entry->ebx & TDX_FEATURE_TSX);
-}
-
-static bool has_waitpkg(const struct kvm_cpuid_entry2 *entry)
-{
- return entry->function == 7 && entry->index == 0 &&
- (entry->ecx & __feature_bit(X86_FEATURE_WAITPKG));
-}
-
-static bool tdx_unsupported_cpuid(const struct kvm_cpuid_entry2 *entry)
-{
- return has_tsx(entry) || has_waitpkg(entry);
-}
-
#define TDX_CPUID_ALL_ALLOWED_MASK GENMASK_U32(31, 0)
static u32 tdx_cfg_non_feature_mask(u32 function, u32 index, int reg)
@@ -2533,6 +2514,17 @@ static int setup_tdparams_eptp_controls(struct kvm_cpuid2 *cpuid,
return 0;
}
+static bool tdx_has_unsupported_cfg_cpuid_bit(const struct kvm_cpuid_entry2 *entry)
+{
+ u32 function = entry->function;
+ u32 index = entry->index;
+
+ return (entry->eax & ~tdx_get_allowed_cfg_cpuid_mask(function, index, CPUID_EAX)) ||
+ (entry->ebx & ~tdx_get_allowed_cfg_cpuid_mask(function, index, CPUID_EBX)) ||
+ (entry->ecx & ~tdx_get_allowed_cfg_cpuid_mask(function, index, CPUID_ECX)) ||
+ (entry->edx & ~tdx_get_allowed_cfg_cpuid_mask(function, index, CPUID_EDX));
+}
+
static int setup_tdparams_cpuids(struct kvm_cpuid2 *cpuid,
struct td_params *td_params)
{
@@ -2556,7 +2548,16 @@ static int setup_tdparams_cpuids(struct kvm_cpuid2 *cpuid,
if (!entry)
continue;
- if (tdx_unsupported_cpuid(entry))
+ /*
+ * Reject entries whose index does not match the expected one.
+ * This catches userspace passing a CPUID entry with the
+ * KVM_CPUID_FLAG_SIGNIFCANT_INDEX flag cleared when the index
+ * is significant.
+ */
+ if (entry->index != tmp.index)
+ return -EINVAL;
+
+ if (tdx_has_unsupported_cfg_cpuid_bit(entry))
return -EINVAL;
copy_cnt++;
--
2.46.0
next prev parent reply other threads:[~2026-08-27 3:14 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-27 3:18 [PATCH v3 0/4] KVM: TDX: Validate directly configurable CPUID bits Binbin Wu
2026-08-27 3:18 ` [PATCH v3 1/4] KVM: TDX: Track configurable CPUID bits allowed by KVM Binbin Wu
2026-08-27 3:18 ` [PATCH v3 2/4] KVM: TDX: Report CORE_CAPABILITIES as configurable Binbin Wu
2026-08-27 3:18 ` [PATCH v3 3/4] KVM: TDX: Filter configurable CPUID bits Binbin Wu
2026-08-27 3:18 ` Binbin Wu [this message]
2026-08-27 3:24 ` [PATCH v3 4/4] KVM: TDX: Validate userspace CPUID input for KVM_TDX_INIT_VM sashiko-bot
2026-08-27 7:25 ` Binbin Wu
2026-08-27 19:33 ` [PATCH v3 0/4] KVM: TDX: Validate directly configurable CPUID bits Edgecombe, Rick P
2026-08-28 3:19 ` Binbin Wu
2026-08-28 16:58 ` Edgecombe, Rick P
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260827031837.2863609-5-binbin.wu@linux.intel.com \
--to=binbin.wu@linux.intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=chao.gao@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=kas@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nik.borisov@suse.com \
--cc=pbonzini@redhat.com \
--cc=rick.p.edgecombe@intel.com \
--cc=seanjc@google.com \
--cc=xiaoyao.li@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox