summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-07-21 19:41:32 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-07-21 19:41:32 +0000
commit74abb919624f39241185aa55c1052973e6162753 (patch)
tree7e68df75396b74c221a60e09fda7c0f9f2d9da57 /sys/arch
parenteea6b80ce1dce633e3e71259f1cdc7bb66f0a3b3 (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.c3
-rw-r--r--sys/arch/amd64/amd64/locore0.S74
-rw-r--r--sys/arch/amd64/amd64/pmap.c4
-rw-r--r--sys/arch/amd64/include/cpu.h3
-rw-r--r--sys/arch/amd64/include/specialreg.h5
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