From: Paul Meyer Date: Thu, 18 Jun 2026 05:44:09 +0000 (+0200) Subject: confidential-virt: read the TDX CPUID leaf unconditionally X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb1bdb9eff2d1026646240951957c310dc2f8b6c;p=thirdparty%2Fsystemd.git confidential-virt: read the TDX CPUID leaf unconditionally 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 --- diff --git a/src/basic/confidential-virt.c b/src/basic/confidential-virt.c index 3f8cb2a3cd8..412fceb2ab4 100644 --- a/src/basic/confidential-virt.c +++ b/src/basic/confidential-virt.c @@ -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)