Show AMD SEV bits during identify CPU in dmesg.
authorbluhm <bluhm@openbsd.org>
Mon, 24 Jun 2024 21:22:14 +0000 (21:22 +0000)
committerbluhm <bluhm@openbsd.org>
Mon, 24 Jun 2024 21:22:14 +0000 (21:22 +0000)
Enable identifycpu() to discover and show AMD SEV related information
provided by cpuid.
The "crypt bit" for page table entries is stored in amd64_pos_cbit,
although it is not used yet.
Registers ecx and edx provide the number of guest and minimum ASID
for SEV-only guests.  At least the latter value can be configured
in the BIOS, so it is useful to have this information in dmesg.
Therefore define emtpy bit masks for printf("%b") to get the raw
numbers.

from hshoexer@; OK mlarkin@

sys/arch/amd64/amd64/identcpu.c
sys/arch/amd64/include/cpu.h
sys/arch/amd64/include/specialreg.h

index ecf130c..1c1df3a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: identcpu.c,v 1.144 2024/06/16 14:01:26 kn Exp $       */
+/*     $OpenBSD: identcpu.c,v 1.145 2024/06/24 21:22:14 bluhm Exp $    */
 /*     $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $        */
 
 /*
@@ -66,6 +66,7 @@ char cpu_model[48];
 int cpuspeed;
 
 int amd64_has_xcrypt;
+int amd64_pos_cbit;
 int has_rdrand;
 int has_rdseed;
 
@@ -695,6 +696,22 @@ identifycpu(struct cpu_info *ci)
                        printf("\n%s: MELTDOWN", ci->ci_dev->dv_xname);
        }
 
+       /* AMD secure memory encryption and encrypted virtualization features */
+       if (ci->ci_vendor == CPUV_AMD &&
+           ci->ci_pnfeatset >= CPUID_AMD_SEV_CAP) {
+               CPUID(CPUID_AMD_SEV_CAP, ci->ci_feature_amdsev_eax,
+                   ci->ci_feature_amdsev_ebx, ci->ci_feature_amdsev_ecx,
+                   ci->ci_feature_amdsev_edx);
+               pcpuid3(ci, "8000001F",
+                   'a', CPUID_MEMBER(ci_feature_amdsev_eax),
+                   CPUID_AMDSEV_EAX_BITS,
+                   'c', CPUID_MEMBER(ci_feature_amdsev_ecx),
+                   CPUID_AMDSEV_ECX_BITS,
+                   'd', CPUID_MEMBER(ci_feature_amdsev_edx),
+                   CPUID_AMDSEV_EDX_BITS);
+               amd64_pos_cbit = (ci->ci_feature_amdsev_ebx & 0x3f);
+       }
+
        printf("\n");
 
        replacemeltdown();
index 82d3552..8bc757c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.173 2024/06/09 21:15:29 jca Exp $   */
+/*     $OpenBSD: cpu.h,v 1.174 2024/06/24 21:22:14 bluhm Exp $ */
 /*     $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $     */
 
 /*-
@@ -170,6 +170,10 @@ struct cpu_info {
        u_int32_t       ci_feature_sefflags_ecx;/* [I] */
        u_int32_t       ci_feature_sefflags_edx;/* [I] */
        u_int32_t       ci_feature_amdspec_ebx; /* [I] */
+       u_int32_t       ci_feature_amdsev_eax;  /* [I] */
+       u_int32_t       ci_feature_amdsev_ebx;  /* [I] */
+       u_int32_t       ci_feature_amdsev_ecx;  /* [I] */
+       u_int32_t       ci_feature_amdsev_edx;  /* [I] */
        u_int32_t       ci_feature_tpmflags;    /* [I] */
        u_int32_t       ci_pnfeatset;           /* [I] */
        u_int32_t       ci_efeature_eax;        /* [I] */
index 834627d..341b1df 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: specialreg.h,v 1.112 2024/05/11 19:21:47 guenther Exp $       */
+/*     $OpenBSD: specialreg.h,v 1.113 2024/06/24 21:22:14 bluhm Exp $  */
 /*     $NetBSD: specialreg.h,v 1.1 2003/04/26 18:39:48 fvdl Exp $      */
 /*     $NetBSD: x86/specialreg.h,v 1.2 2003/04/25 21:54:30 fvdl Exp $  */
 
      "\022STIBP_ALL" "\023IBRS_PREF" "\024IBRS_SM" "\031SSBD" "\032VIRTSSBD" \
      "\033SSBDNR" )
 
+/*
+ * AMD CPUID function 0x8000001F EAX bits
+ */
+#define CPUIDEAX_SME           (1ULL << 0)  /* SME */
+#define CPUIDEAX_SEV           (1ULL << 1)  /* SEV */
+#define CPUIDEAX_PFLUSH_MSR    (1ULL << 2)  /* Page Flush MSR */
+#define CPUIDEAX_SEVES         (1ULL << 3)  /* SEV-ES */
+#define CPUIDEAX_SEVSNP                (1ULL << 4)  /* SEV-SNP */
+#define CPUIDEAX_VMPL          (1ULL << 5)  /* VM Permission Levels */
+#define CPUIDEAX_RMPQUERY      (1ULL << 6)  /* RMPQUERY */
+#define CPUIDEAX_VMPLSSS       (1ULL << 7)  /* VMPL Supservisor Shadow Stack */
+#define CPUIDEAX_SECTSC                (1ULL << 8)  /* Secure TSC */
+#define CPUIDEAX_TSCAUXVIRT    (1ULL << 9)  /* TSC Aux Virtualization */
+#define CPUIDEAX_HWECACHECOH   (1ULL << 10) /* Coherency Across Enc. Domains */
+#define CPUIDEAX_64BITHOST     (1ULL << 11) /* SEV guest requires 64bit host */
+#define CPUIDEAX_RESTINJ       (1ULL << 12) /* Restricted Injection */
+#define CPUIDEAX_ALTINJ                (1ULL << 13) /* Alternate Injection */
+#define CPUIDEAX_DBGSTSW       (1ULL << 14) /* Full debug state swap */
+#define CPUIDEAX_IBSDISALLOW   (1ULL << 15) /* Disallowing IBS use by host */
+#define CPUIDEAX_VTE           (1ULL << 16) /* Virt. Transparent Encryption */
+#define CPUIDEAX_VMGEXITPARAM  (1ULL << 17) /* VMGEXIT Parameter */
+#define CPUIDEAX_VTOMMSR       (1ULL << 18) /* Virtual TOM MSR */
+#define CPUIDEAX_IBSVIRT       (1ULL << 19) /* IBS Virtualization for SEV-ES */
+#define CPUIDEAX_VMSARPROT     (1ULL << 24) /* VMSA Register Protection */
+#define CPUIDEAX_SMTPROT       (1ULL << 25) /* SMT Protection */
+#define CPUIDEAX_SVSMPAGEMSR   (1ULL << 28) /* SVSM Communication Page MSR */
+#define CPUIDEAX_NVSMSR                (1ULL << 29) /* NestedVirtSnpMsr */
+#define CPUID_AMDSEV_EAX_BITS \
+    ("\20" "\01SME" "\02SEV" "\03PFLUSH_MSR" "\04SEVES" "\05SEVSNP" "\06VMPL" \
+     "\07RMPQUERY" "\010VMPLSSS" "\011SECTSC" "\012TSCAUXVIRT" \
+     "\013HWECACHECOH" "\014REQ64BITHOST" "\015RESTINJ" "\016ALTINJ" \
+     "\017DBGSTSW" "\020IBSDISALLOW" "\021VTE" "\022VMGEXITPARAM" \
+     "\023VTOMMSR" "\024IBSVIRT" "\031VMSARPROT" "\032SMTPROT" \
+     "\035SVSMPAGEMSR" "\036NVSMSR" )
+
+/* Number of encrypted guests */
+#define CPUID_AMDSEV_ECX_BITS ("\20")
+
+/* Minimum ASID for SEV enabled, SEV-ES disabled guest. */
+#define CPUID_AMDSEV_EDX_BITS ("\20")
+
 #define        CPUID2FAMILY(cpuid)     (((cpuid) >> 8) & 15)
 #define        CPUID2MODEL(cpuid)      (((cpuid) >> 4) & 15)
 #define        CPUID2STEPPING(cpuid)   ((cpuid) & 15)
 #define SVM_INTERCEPT_CR14_WRITE_POST  (1UL << 30)
 #define SVM_INTERCEPT_CR15_WRITE_POST  (1UL << 31)
 
+/*
+ * SME and SEV
+ */
+#define CPUID_AMD_SEV_CAP              0x8000001F
+#define AMD_SME_CAP                    (1UL << 0)
+#define AMD_SEV_CAP                    (1UL << 1)
+
 /*
  * PAT
  */