]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Fix detection of TDX confidential VM on Azure platform
authorDaniel P. Berrangé <berrange@redhat.com>
Tue, 30 Jul 2024 09:51:21 +0000 (10:51 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 30 Jul 2024 20:39:20 +0000 (22:39 +0200)
The original CVM detection logic for TDX assumes that the guest can see
the standard TDX CPUID leaf. This was true in Azure when this code was
originally written, however, current Azure now blocks that leaf in the
paravisor. Instead it is required to use the same Azure specific CPUID
leaf that is used for SEV-SNP detection, which reports the VM isolation
type.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/basic/confidential-virt.c
src/boot/efi/vmm.c
src/fundamental/confidential-virt-fundamental.h

index b6521cf5bfcfe008bac76472f07ed2fbcf3dd135..8a88a3eb83101864a067cebeb70d32b5314ec9fd 100644 (file)
@@ -76,7 +76,7 @@ static uint64_t msr(uint64_t index) {
         return ret;
 }
 
-static bool detect_hyperv_sev(void) {
+static bool detect_hyperv_cvm(uint32_t isoltype) {
         uint32_t eax, ebx, ecx, edx, feat;
         char sig[13] = {};
 
@@ -100,7 +100,7 @@ static bool detect_hyperv_sev(void) {
                 ebx = ecx = edx = 0;
                 cpuid(&eax, &ebx, &ecx, &edx);
 
-                if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == CPUID_HYPERV_ISOLATION_TYPE_SNP)
+                if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == isoltype)
                         return true;
         }
 
@@ -133,7 +133,7 @@ static ConfidentialVirtualization detect_sev(void) {
         if (!(eax & EAX_SEV)) {
                 log_debug("No sev in CPUID, trying hyperv CPUID");
 
-                if (detect_hyperv_sev())
+                if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_SNP))
                         return CONFIDENTIAL_VIRTUALIZATION_SEV_SNP;
 
                 log_debug("No hyperv CPUID");
@@ -171,6 +171,11 @@ static ConfidentialVirtualization detect_tdx(void) {
         if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0)
                 return CONFIDENTIAL_VIRTUALIZATION_TDX;
 
+        log_debug("No tdx in CPUID, trying hyperv CPUID");
+
+        if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_TDX))
+                return CONFIDENTIAL_VIRTUALIZATION_TDX;
+
         return CONFIDENTIAL_VIRTUALIZATION_NONE;
 }
 
index 87b692cc8561e73e5c16acb0a8c76d8210d3666e..7d7d0d138272ef0c0e6aa35fb421c0edb0d446b8 100644 (file)
@@ -347,7 +347,7 @@ static uint64_t msr(uint32_t index) {
         return val;
 }
 
-static bool detect_hyperv_sev(void) {
+static bool detect_hyperv_cvm(uint32_t isoltype) {
         uint32_t eax, ebx, ecx, edx, feat;
         char sig[13] = {};
 
@@ -364,7 +364,7 @@ static bool detect_hyperv_sev(void) {
         if (ebx & CPUID_HYPERV_ISOLATION && !(ebx & CPUID_HYPERV_CPU_MANAGEMENT)) {
                 __cpuid(CPUID_HYPERV_ISOLATION_CONFIG, eax, ebx, ecx, edx);
 
-                if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == CPUID_HYPERV_ISOLATION_TYPE_SNP)
+                if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == isoltype)
                         return true;
         }
 
@@ -389,7 +389,7 @@ static bool detect_sev(void) {
          * specific CPUID checks.
          */
         if (!(eax & EAX_SEV))
-                return detect_hyperv_sev();
+                return detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_SNP);
 
         msrval = msr(MSR_AMD64_SEV);
 
@@ -413,6 +413,9 @@ static bool detect_tdx(void) {
         if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0)
                 return true;
 
+        if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_TDX))
+                return true;
+
         return false;
 }
 #endif /* ! __i386__ && ! __x86_64__ */
index 986923e1c2b4e309bb17715cd9cb3b6c7e7e6a89..618b5800ea4bcc27b2f352edabdf1ade9b657bce 100644 (file)
@@ -65,6 +65,7 @@
 
 #define CPUID_HYPERV_ISOLATION_TYPE_MASK UINT32_C(0xf)
 #define CPUID_HYPERV_ISOLATION_TYPE_SNP 2
+#define CPUID_HYPERV_ISOLATION_TYPE_TDX 3
 
 #define EAX_SEV     (UINT32_C(1) << 1)
 #define MSR_SEV     (UINT64_C(1) << 0)