diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-07-21 19:41:32 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-07-21 19:41:32 +0000 |
commit | 74abb919624f39241185aa55c1052973e6162753 (patch) | |
tree | 7e68df75396b74c221a60e09fda7c0f9f2d9da57 /sys/arch | |
parent | eea6b80ce1dce633e3e71259f1cdc7bb66f0a3b3 (diff) |
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@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 3 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/locore0.S | 74 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/pmap.c | 4 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/amd64/include/specialreg.h | 5 |
5 files changed, 84 insertions, 5 deletions
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 $ */ /* @@ -269,6 +269,78 @@ 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 * clobbering the memory test or the zeroing of the bss+bootstrap page 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 |