You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.4 KiB
118 lines
3.4 KiB
From eecffe8b20d7e136e64d7360ef6655c8eee4250e Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
|
Date: Thu, 29 Jun 2023 17:51:04 +0100
|
|
Subject: [PATCH] virt-what-cvm: probe for SNP/HCL on HyperV/Azure via CPUID
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
When running a confidential VM on Azure (HyperV) we can probe
|
|
CPUID leaf 0x40000003 to detect if VM isolation is present,
|
|
and 0x4000000c to detect what kind of isolation is used.
|
|
|
|
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
(cherry picked from commit bb0055b491501e16fca3ab61dc7a969effbf48f3)
|
|
---
|
|
virt-what-cvm.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++--
|
|
1 file changed, 60 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/virt-what-cvm.c b/virt-what-cvm.c
|
|
index 1e7c50bb0..a7a224f94 100644
|
|
--- a/virt-what-cvm.c
|
|
+++ b/virt-what-cvm.c
|
|
@@ -70,14 +70,33 @@ static bool dodebug = false;
|
|
|
|
#define CPUID_INTEL_TDX_ENUMERATION 0x21
|
|
|
|
+/* Requirements for Implementing the Microsoft Hypervisor Interface
|
|
+ * https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs
|
|
+ */
|
|
+#define CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS 0x40000000
|
|
+
|
|
+#define CPUID_HYPERV_FEATURES 0x40000003
|
|
+
|
|
+#define CPUID_HYPERV_ISOLATION_CONFIG 0x4000000C
|
|
+
|
|
+#define CPUID_HYPERV_MIN 0x40000005
|
|
+#define CPUID_HYPERV_MAX 0x4000ffff
|
|
|
|
#define CPUID_SIG_AMD "AuthenticAMD"
|
|
#define CPUID_SIG_INTEL "GenuineIntel"
|
|
#define CPUID_SIG_INTEL_TDX "IntelTDX "
|
|
+#define CPUID_SIG_HYPERV "Microsoft Hv"
|
|
|
|
/* ecx bit 31: set => hyperpvisor, unset => bare metal */
|
|
#define CPUID_FEATURE_HYPERVISOR (1 << 31)
|
|
|
|
+/* Linux include/asm-generic/hyperv-tlfs.h */
|
|
+#define CPUID_HYPERV_CPU_MANAGEMENT (1 << 12) /* root partition */
|
|
+#define CPUID_HYPERV_ISOLATION (1 << 22) /* confidential VM partition */
|
|
+
|
|
+#define CPUID_HYPERV_ISOLATION_TYPE_MASK 0xf
|
|
+#define CPUID_HYPERV_ISOLATION_TYPE_SNP 2
|
|
+
|
|
/*
|
|
* This TPM NV data format is not explicitly documented anywhere,
|
|
* but the header definition is present in code at:
|
|
@@ -272,6 +291,44 @@ cpu_sig_amd_azure (void)
|
|
return ret;
|
|
}
|
|
|
|
+static bool
|
|
+cpu_sig_amd_hyperv (void)
|
|
+{
|
|
+ uint32_t eax, ebx, ecx, edx;
|
|
+ char sig[13];
|
|
+ uint32_t feat;
|
|
+
|
|
+ feat = cpuid_leaf (CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS, sig, false);
|
|
+
|
|
+ if (feat < CPUID_HYPERV_MIN ||
|
|
+ feat > CPUID_HYPERV_MAX)
|
|
+ return false;
|
|
+
|
|
+ if (memcmp (sig, CPUID_SIG_HYPERV, sizeof(sig)) != 0)
|
|
+ return false;
|
|
+
|
|
+ debug ("CPUID is on hyperv\n");
|
|
+ eax = CPUID_HYPERV_FEATURES;
|
|
+ ebx = ecx = edx = 0;
|
|
+
|
|
+ cpuid(&eax, &ebx, &ecx, &edx);
|
|
+
|
|
+ if (ebx & CPUID_HYPERV_ISOLATION &&
|
|
+ !(ebx & CPUID_HYPERV_CPU_MANAGEMENT)) {
|
|
+
|
|
+ eax = CPUID_HYPERV_ISOLATION_CONFIG;
|
|
+ ebx = ecx = edx = 0;
|
|
+ cpuid(&eax, &ebx, &ecx, &edx);
|
|
+
|
|
+ if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) ==
|
|
+ CPUID_HYPERV_ISOLATION_TYPE_SNP) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
static void
|
|
cpu_sig_amd (void)
|
|
{
|
|
@@ -298,9 +355,10 @@ cpu_sig_amd (void)
|
|
* exposes a SEV-SNP attestation report as evidence.
|
|
*/
|
|
if (!(eax & (1 << 1))) {
|
|
- debug ("No sev in CPUID, try azure TPM NV\n");
|
|
+ debug ("No sev in CPUID, try hyperv CPUID/azure TPM NV\n");
|
|
|
|
- if (cpu_sig_amd_azure()) {
|
|
+ if (cpu_sig_amd_hyperv () ||
|
|
+ cpu_sig_amd_azure()) {
|
|
puts ("amd-sev-snp");
|
|
puts ("azure-hcl");
|
|
} else {
|
|
--
|
|
2.43.0
|
|
|