detect_tdx() guarded the read of the TDX enumeration leaf (0x21, a
standard leaf) with CPUID_GET_HIGHEST_FUNCTION (0x80000000), which
returns the highest *extended* function. eax is therefore always
>= 0x80000000, so the "eax < 0x21" guard never held and the leaf was
read unconditionally anyway.
Drop the guard rather than re-gate it on the basic max function
(leaf 0), and read 0x21 directly, relying on the IntelTDX signature
compare. This matches the kernel, which reads the leaf unconditionally
on purpose: an out-of-range CPUID leaf returns the highest basic leaf's
data (no fault, per the Intel SDM), and 0x21 is a synthetic TDX leaf
whose presence need not be reflected in the reported max basic function,
so gating the read on it risks missing a genuine TDX guest. With no
guard the Hyper-V isolation fallback (Azure TDX guests have 0x21
blocked) also stays reachable.
Ref: Linux
59bd54a84d15 ("x86/tdx: Detect running as a TDX guest in
early boot"), arch/x86/coco/tdx/tdx.c:1119 (tdx_early_init()).
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
}
static ConfidentialVirtualization detect_tdx(void) {
- uint32_t eax, ebx, ecx, edx;
char sig[13] = {};
- eax = CPUID_GET_HIGHEST_FUNCTION;
- ebx = ecx = edx = 0;
-
- cpuid(&eax, &ebx, &ecx, &edx);
-
- if (eax < CPUID_INTEL_TDX_ENUMERATION)
- return CONFIDENTIAL_VIRTUALIZATION_NONE;
-
+ /* Querying an unsupported CPUID leaf is harmless (it returns the highest basic leaf's data rather
+ * than faulting), so reading this leaf and matching the IntelTDX signature is sufficient. */
cpuid_leaf(CPUID_INTEL_TDX_ENUMERATION, sig, true);
if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0)