From: bluhm Date: Sun, 21 Jul 2024 19:41:31 +0000 (+0000) Subject: For AMD SEV determine C-bit position and guest mode in locore0. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=72a0fbccc5614cd17790b645bf66f82f63c67207;p=openbsd For AMD SEV determine C-bit position and guest mode in locore0. Actually determine the C-bit position if we are running as a guest with SEV enabled. Configure pg_crypt, pg_frame and pg_lgframe accordingly, using the physical address bit reduction provided by cpuid. from hshoexer@; OK mlarkin@ --- diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index 8df6de03b89..898c23010f3 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.190 2024/06/07 16:53:35 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.191 2024/07/21 19:41:31 bluhm Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -157,6 +157,7 @@ int cpu_ebxfeature = 0; /* cpuid(1).ebx */ int cpu_ecxfeature = 0; /* INTERSECTION(cpuid(1).ecx) */ int cpu_feature = 0; /* cpuid(1).edx */ int ecpu_ecxfeature = 0; /* cpuid(0x80000001).ecx */ +int cpu_sev_guestmode = 0; int cpu_meltdown = 0; int cpu_use_xsaves = 0; int need_retpoline = 1; /* most systems need retpoline */ diff --git a/sys/arch/amd64/amd64/locore0.S b/sys/arch/amd64/amd64/locore0.S index bbfed3aa963..bc45eee7a09 100644 --- a/sys/arch/amd64/amd64/locore0.S +++ b/sys/arch/amd64/amd64/locore0.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore0.S,v 1.24 2024/07/10 12:36:13 bluhm Exp $ */ +/* $OpenBSD: locore0.S,v 1.25 2024/07/21 19:41:31 bluhm Exp $ */ /* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ /* @@ -268,6 +268,78 @@ bi_size_ok: cont: orl %edx, RELOC(cpu_feature) + /* + * Determine AMD SME and SEV capabilities. + */ + movl $RELOC(cpu_vendor),%ebp + cmpl $0x68747541, (%ebp) /* "Auth" */ + jne .Lno_smesev + cmpl $0x69746e65, 4(%ebp) /* "enti" */ + jne .Lno_smesev + cmpl $0x444d4163, 8(%ebp) /* "cAMD" */ + jne .Lno_smesev + + /* AMD CPU, check for SME and SEV. */ + movl $0x8000001f, %eax + cpuid + pushl %eax + andl $CPUIDEAX_SME, %eax /* SME */ + popl %eax + jz .Lno_smesev + andl $CPUIDEAX_SEV, %eax /* SEV */ + jz .Lno_smesev + + /* Are we in guest mode with SEV enabled? */ + movl $MSR_SEV_STATUS, %ecx + rdmsr + andl $SEV_STAT_ENABLED, %eax + jz .Lno_smesev + + /* Determine C bit position */ + movl %ebx, %ecx /* %ebx from previous cpuid */ + andl $0x3f, %ecx + cmpl $0x20, %ecx /* must be at least bit 32 (counting from 0) */ + jl .Lno_smesev + xorl %eax, %eax + movl %eax, RELOC(pg_crypt) + subl $0x20, %ecx + movl $0x1, %eax + shll %cl, %eax + movl %eax, RELOC((pg_crypt + 4)) + + /* + * Determine physical address reduction. Adjust page frame masks. + * + * The top 12 bits of a physical address are reserved and + * supposed to be 0. Thus PG_FRAME masks of the top 12 bits + * and low 10 bits (offset into page). PG_LGFRAME is defined + * similarly. + * + * According to the number of reduction bits we shrink the + * page frame masks beginning at bit 51. + * + * E.g. with a 5 bit reduction PG_FRAME will be reduced from + * 0x000ffffffffff000 to 0x00007ffffffff000. + * + * One of the now freed bits will be used as the C bit, e.g. + * bit 51. + */ + movl %ebx, %ecx /* %ebx from previous cpuid */ + andl $0xfc0, %ecx + shrl $6, %ecx /* number of bits to reduce */ + + movl $1, %eax /* calculate mask */ + shll $20, %eax + shrl %cl, %eax + decl %eax + + andl %eax, RELOC(pg_frame + 4) /* apply mask */ + andl %eax, RELOC(pg_lgframe + 4) + + movl $0x1, RELOC(cpu_sev_guestmode) /* we are a SEV guest */ + +.Lno_smesev: + /* * Finished with old stack; load new %esp now instead of later so we * can trace this code without having to worry about the trace trap diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index 0c3fe07cd69..f8c4acea310 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.169 2024/07/09 19:11:06 bluhm Exp $ */ +/* $OpenBSD: pmap.c,v 1.170 2024/07/21 19:41:31 bluhm Exp $ */ /* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ /* @@ -660,6 +660,8 @@ pmap_bootstrap(paddr_t first_avail, paddr_t max_pa) vaddr_t kva, kva_end; pt_entry_t *pml3, *pml2; + KASSERT(((0x1000ULL | pg_crypt) & pg_frame) == 0x1000ULL); + /* * define the boundaries of the managed kernel virtual address * space. diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index 8bc757ccc91..f5aada4d4d3 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.174 2024/06/24 21:22:14 bluhm Exp $ */ +/* $OpenBSD: cpu.h,v 1.175 2024/07/21 19:41:31 bluhm Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -398,6 +398,7 @@ extern int cpu_feature; extern int cpu_ebxfeature; extern int cpu_ecxfeature; extern int ecpu_ecxfeature; +extern int cpu_sev_guestmode; extern int cpu_id; extern char cpu_vendor[]; extern int cpuid_level; diff --git a/sys/arch/amd64/include/specialreg.h b/sys/arch/amd64/include/specialreg.h index 7d1a0804a0c..a8a7e492a17 100644 --- a/sys/arch/amd64/include/specialreg.h +++ b/sys/arch/amd64/include/specialreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: specialreg.h,v 1.114 2024/07/14 07:57:42 dv Exp $ */ +/* $OpenBSD: specialreg.h,v 1.115 2024/07/21 19:41:31 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 $ */ @@ -713,6 +713,9 @@ #define NB_CFG_DISIOREQLOCK 0x0000000000000004ULL #define NB_CFG_DISDATMSK 0x0000001000000000ULL +#define MSR_SEV_STATUS 0xc0010131 +#define SEV_STAT_ENABLED 0x00000001 + #define MSR_LS_CFG 0xc0011020 #define LS_CFG_DIS_LS2_SQUISH 0x02000000