]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
confidential-virt: read the TDX CPUID leaf unconditionally
authorPaul Meyer <katexochen0@gmail.com>
Thu, 18 Jun 2026 05:44:09 +0000 (07:44 +0200)
committerPaul Meyer <katexochen0@gmail.com>
Tue, 23 Jun 2026 10:35:54 +0000 (12:35 +0200)
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>
src/basic/confidential-virt.c

index 3f8cb2a3cd81fbc82c32c15ae0531beaa0fed756..412fceb2ab4c61808a2d12222d3baaf86419b6ce 100644 (file)
@@ -159,17 +159,10 @@ static ConfidentialVirtualization detect_sev(void) {
 }
 
 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)