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 <katexochen0@gmail.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user