From f880dfaf25f9138303b97de5f41f09576faa7c47 Mon Sep 17 00:00:00 2001 From: bluhm Date: Mon, 24 Jun 2024 21:22:14 +0000 Subject: [PATCH] Show AMD SEV bits during identify CPU in dmesg. 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 | 19 ++++++++++- sys/arch/amd64/include/cpu.h | 6 +++- sys/arch/amd64/include/specialreg.h | 50 ++++++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c index ecf130c393f..1c1df3a11a1 100644 --- a/sys/arch/amd64/amd64/identcpu.c +++ b/sys/arch/amd64/amd64/identcpu.c @@ -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(); diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index 82d3552c43e..8bc757ccc91 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -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] */ diff --git a/sys/arch/amd64/include/specialreg.h b/sys/arch/amd64/include/specialreg.h index 834627d8c7d..341b1df2309 100644 --- a/sys/arch/amd64/include/specialreg.h +++ b/sys/arch/amd64/include/specialreg.h @@ -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 $ */ @@ -395,6 +395,47 @@ "\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) @@ -1547,6 +1588,13 @@ #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 */ -- 2.20.1