-/* $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 $ */
/*-
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 */
-/* $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 $ */
/*
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
-/* $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 $ */
/*-
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;
-/* $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 $ */
#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