Index | Thread | Search

From:
Hans-Jörg Höxer <hshoexer@genua.de>
Subject:
Re: [EXT] Re: SEV-SNP: Prepare for SNP page validation 1/4
To:
<tech@openbsd.org>
Cc:
<Hans-Joerg_Hoexer@genua.de>
Date:
Tue, 18 Aug 2026 13:22:00 +0200

Download raw body.

Thread
On Mon, Aug 17, 2026 at 09:50:51AM -0600, Theo de Raadt wrote:
> Looks good.  Did you see any code which can move so that one #ifdef
> covers two chunks?
> 

in locore0 I could move a chunk around and save one #ifdef.  Updated diff
below.

ok?

Take care,
HJ.
-----------------------
Subject: SEV: Add option AMDSEV

To allow building the small RAMDISK kernel without SEV-* support
introduce the option AMDSEV.

When running a non-SEV kernel as a SEV guest we will raise a #VC
exception on the very first CPUID instruction.  To allow a somehwat
graceful termination keep the locore0 #VC trap handler, fall through
to the termination code and issue  TERMINATION request to the
hypervisor.  In all other environments #VC will never be raised and
the kernel runs normally.

Build RAMDISK without SEV-* support, all other kernel keep SEV-*
support.

While there, cleanup and unify some definitions of the MSR protocol.
---
 sys/arch/amd64/amd64/bus_space.c   |  7 +++++++
 sys/arch/amd64/amd64/locore0.S     | 27 +++++++++++++++------------
 sys/arch/amd64/amd64/machdep.c     |  4 ++++
 sys/arch/amd64/amd64/trap.c        |  8 ++++++++
 sys/arch/amd64/amd64/vector.S      |  6 ++++++
 sys/arch/amd64/amd64/vmm_machdep.c |  2 +-
 sys/arch/amd64/conf/GENERIC        |  1 +
 sys/arch/amd64/conf/RAMDISK_CD     |  1 +
 sys/arch/amd64/conf/VMBOOT         |  1 +
 sys/arch/amd64/conf/files.amd64    |  4 ++--
 sys/arch/amd64/include/ghcb.h      | 30 ++++++++++++++++++++++--------
 11 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/sys/arch/amd64/amd64/bus_space.c b/sys/arch/amd64/amd64/bus_space.c
index 9439ca6b954..376c64ed13c 100644
--- a/sys/arch/amd64/amd64/bus_space.c
+++ b/sys/arch/amd64/amd64/bus_space.c
@@ -317,8 +317,10 @@ const struct x86_bus_space_ops default_bus_space_mem_ops = {
 
 const struct x86_bus_space_ops *x86_bus_space_mem_ops;
 
+#ifdef AMDSEV
 extern const struct x86_bus_space_ops sev_ghcb_bus_space_io_ops;
 extern const struct x86_bus_space_ops sev_ghcb_bus_space_mem_ops;
+#endif
 
 void
 x86_bus_space_init(void)
@@ -341,6 +343,7 @@ x86_bus_space_init(void)
 	    (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage),
 	    EX_NOCOALESCE|EX_NOWAIT);
 
+#ifdef AMDSEV
 	if (ISSET(cpu_sev_guestmode, SEV_STAT_ES_ENABLED)) {
 		x86_bus_space_mem_ops = &sev_ghcb_bus_space_mem_ops;
 		x86_bus_space_io_ops  = &sev_ghcb_bus_space_io_ops;
@@ -348,6 +351,10 @@ x86_bus_space_init(void)
 		x86_bus_space_mem_ops = &default_bus_space_mem_ops;
 		x86_bus_space_io_ops  = &default_bus_space_io_ops;
 	}
+#else
+	x86_bus_space_mem_ops = &default_bus_space_mem_ops;
+	x86_bus_space_io_ops  = &default_bus_space_io_ops;
+#endif
 }
 
 void
diff --git a/sys/arch/amd64/amd64/locore0.S b/sys/arch/amd64/amd64/locore0.S
index f8ba97805ce..d0466ab82e1 100644
--- a/sys/arch/amd64/amd64/locore0.S
+++ b/sys/arch/amd64/amd64/locore0.S
@@ -810,19 +810,9 @@ longmode_hi:
 	call	main
 
 	.code32
-vc_cpuid32:
-	shll	$30, %eax		/* requested register */
-	orl	$MSR_PROTO_CPUID_REQ, %eax
-	movl	%ebx, %edx		/* CPUID function */
-	movl	$MSR_SEV_GHCB, %ecx
-	wrmsr
-	rep vmmcall
-	rdmsr
-	ret
-	lfence
-
 	.globl	locore_vc_trap32
 locore_vc_trap32:
+#ifdef AMDSEV
 	pushl	%eax
 	pushl	%ebx
 	pushl	%ecx
@@ -871,8 +861,21 @@ locore_vc_trap32:
 	addl	$3, (%esp)		/* skip mov,%db */
 	iret
 
+vc_cpuid32:
+	shll	$30, %eax		/* requested register */
+	orl	$MSR_PROTO_CPUID_REQ, %eax
+	movl	%ebx, %edx		/* CPUID function */
+	movl	$MSR_SEV_GHCB, %ecx
+	wrmsr
+	rep vmmcall
+	rdmsr
+	ret
+	lfence
+#endif	/* AMDSEV */
+	/* !AMDSEV: FALLTHROUGH and graceful termination */
+
 .Lterminate32:
-	movl	$MSR_PROTO_TERMINATE, %eax
+	movl	$MSR_PROTO_TERMINATION_REQ, %eax
 	movl	$MSR_SEV_GHCB, %ecx
 	wrmsr
 	rep vmmcall
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index bbf1e415962..6891733bd24 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1335,6 +1335,7 @@ cpu_init_idt(void)
 	lidt(&region);
 }
 
+#ifdef AMDSEV
 uint64_t early_gdt[GDT_SIZE / 8];
 
 void
@@ -1366,6 +1367,7 @@ cpu_init_early_vctrap(paddr_t addr)
 	memset((void *)ghcb_vaddr, 0, 2 * PAGE_SIZE);
 	wrmsr(MSR_SEV_GHCB, ghcb_paddr);
 }
+#endif	/* AMDSEV */
 
 void
 cpu_init_extents(void)
@@ -1494,6 +1496,7 @@ init_x86_64(paddr_t first_avail)
 	    ((pmap_direct_rand & DIRECT_MAP_START_MASK) * NBPD_L4))));
 	pmap_direct_end = pmap_direct_base + DIRECT_MAP_SIZE;
 
+#ifdef AMDSEV
 	/*
 	 * locore0 mapped 2 pages for use as GHCB before pmap is initialized.
 	 */
@@ -1503,6 +1506,7 @@ init_x86_64(paddr_t first_avail)
 	}
 	if (ISSET(cpu_sev_guestmode, SEV_STAT_ENABLED))
 		boothowto |= RB_COCOVM;
+#endif
 
 	/*
 	 * locore0 mapped 3 pages for use before the pmap is initialized
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index ccd0315186c..95d57b59f5a 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -97,7 +97,9 @@
 
 int	upageflttrap(struct trapframe *, uint64_t);
 int	kpageflttrap(struct trapframe *, uint64_t);
+#ifdef AMDSEV
 int	vctrap(struct trapframe *, int, int *, int *);
+#endif
 void	kerntrap(struct trapframe *);
 void	usertrap(struct trapframe *);
 void	ast(struct trapframe *);
@@ -301,6 +303,7 @@ kpageflttrap(struct trapframe *frame, uint64_t cr2)
 	return 1;
 }
 
+#ifdef AMDSEV
 int
 vctrap(struct trapframe *frame, int user, int *sig, int *code)
 {
@@ -492,6 +495,7 @@ vctrap(struct trapframe *frame, int user, int *sig, int *code)
 
 	return 1;
 }
+#endif	/* AMDSEV */
 
 
 /*
@@ -545,10 +549,12 @@ kerntrap(struct trapframe *frame)
 			return;
 #endif /* NISA > 0 */
 
+#ifdef AMDSEV
 	case T_VC:
 		if (vctrap(frame, 0, NULL, NULL))
 			return;
 		goto we_re_toast;
+#endif
 	}
 }
 
@@ -628,10 +634,12 @@ usertrap(struct trapframe *frame)
 		code = (frame->tf_err & 0x7fff) < 4 ? ILL_BTCFI
 		    : ILL_BADSTK;
 		break;
+#ifdef AMDSEV
 	case T_VC:
 		if (vctrap(frame, 1, &sig, &code))
 			goto out;
 		break;
+#endif
 	case T_PAGEFLT:			/* page fault */
 		if (!uvm_map_inentry(p, &p->p_spinentry, PROC_STACK(p),
 		    "[%s]%d/%d sp=%lx inside %lx-%lx: not MAP_STACK\n",
diff --git a/sys/arch/amd64/amd64/vector.S b/sys/arch/amd64/amd64/vector.S
index 9de0ee97f08..354f29a06a3 100644
--- a/sys/arch/amd64/amd64/vector.S
+++ b/sys/arch/amd64/amd64/vector.S
@@ -375,6 +375,7 @@ IDTVEC(trap14)
 IDTVEC(trap15)
 	TRAP(T_CP)
 
+#ifdef AMDSEV
 IDTVEC(trap1d)
 	/*
 	 * #VC is AMD CPU specific, thus we don't use any Intel Meltdown
@@ -408,6 +409,9 @@ vctrap_kern:
 	SMAP_CLAC
 	/* shortcut to regular path, but with interrupts disabled */
 	jmp	.Lreal_kern_trap
+#else
+IDTVEC_ALIAS(trap1d, trap1f)
+#endif	/* AMDSEV */
 
 IDTVEC(trap1f)
 IDTVEC_ALIAS(trap16, trap1f)
@@ -548,6 +552,7 @@ END(alltraps_kern)
 END(alltraps_kern_meltdown)
 KTEXT_PAGE_END
 
+#ifdef AMDSEV
 /* #VC trap entry for early bootstrap */
 IDTVEC(vctrap_early)
 	pushq	$T_VC
@@ -558,6 +563,7 @@ IDTVEC(vctrap_early)
 	call	vctrap
 	movq	$0,-8(%rsp)
 	INTRFASTEXIT
+#endif
 
 /*
  * Macros for interrupt entry, call to handler, and exit.
diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c
index 787b65e29e1..850010abb90 100644
--- a/sys/arch/amd64/amd64/vmm_machdep.c
+++ b/sys/arch/amd64/amd64/vmm_machdep.c
@@ -4523,7 +4523,7 @@ svm_handle_vmgexit(struct vcpu *vcpu)
 		req = (vmcb->v_ghcb_gpa & 0xffffffff);
 
 		/* We only support cpuid and terminate. */
-		if ((req & ~PG_FRAME) == MSR_PROTO_TERMINATE) {
+		if ((req & ~PG_FRAME) == MSR_PROTO_TERMINATION_REQ) {
 			DPRINTF("%s: guest requests termination\n", __func__);
 			return (1);
 		} else if ((req & ~PG_FRAME) != MSR_PROTO_CPUID_REQ)
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC
index c3680e2fb21..fe6a8c62f6f 100644
--- a/sys/arch/amd64/conf/GENERIC
+++ b/sys/arch/amd64/conf/GENERIC
@@ -21,6 +21,7 @@ option		MTRR		# CPU memory range attributes control
 option		NTFS		# NTFS support
 option		SUSPEND
 option		HIBERNATE
+option		AMDSEV
 
 config		bsd	swap generic
 
diff --git a/sys/arch/amd64/conf/RAMDISK_CD b/sys/arch/amd64/conf/RAMDISK_CD
index 82cf1b89a25..b7ee25adef0 100644
--- a/sys/arch/amd64/conf/RAMDISK_CD
+++ b/sys/arch/amd64/conf/RAMDISK_CD
@@ -19,6 +19,7 @@ option		UDF
 option		MSDOSFS
 option		INET6
 option		CRYPTO
+option		AMDSEV
 
 option		FONT_SPLEEN8x16
 option		FONT_SPLEEN12x24
diff --git a/sys/arch/amd64/conf/VMBOOT b/sys/arch/amd64/conf/VMBOOT
index 5a615b98288..68ba0d7773b 100644
--- a/sys/arch/amd64/conf/VMBOOT
+++ b/sys/arch/amd64/conf/VMBOOT
@@ -7,6 +7,7 @@ option		BOOT_KERNEL
 option		SMALL_KERNEL
 option		NO_PROPOLICE
 option		BOOT_CONFIG
+option		AMDSEV
 
 option		RAMDISK_HOOKS
 option		MINIROOTSIZE=4480
diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64
index 0c1e224f5c2..ebd75315eb8 100644
--- a/sys/arch/amd64/conf/files.amd64
+++ b/sys/arch/amd64/conf/files.amd64
@@ -28,8 +28,8 @@ file	arch/amd64/amd64/vm_machdep.c
 file	arch/amd64/amd64/fpu.c
 file	arch/amd64/amd64/i8259.c
 file	arch/amd64/amd64/cacheinfo.c
-file	arch/amd64/amd64/ghcb.c
-file	arch/amd64/amd64/sev_bus_space.c
+file	arch/amd64/amd64/ghcb.c			amdsev
+file	arch/amd64/amd64/sev_bus_space.c	amdsev
 file	arch/amd64/amd64/vector.S
 file	arch/amd64/amd64/copy.S
 file	arch/amd64/amd64/spl.S
diff --git a/sys/arch/amd64/include/ghcb.h b/sys/arch/amd64/include/ghcb.h
index 55e184186ab..104e36dda87 100644
--- a/sys/arch/amd64/include/ghcb.h
+++ b/sys/arch/amd64/include/ghcb.h
@@ -19,6 +19,8 @@
 #ifndef _MACHINE_GHCB_H_
 #define _MACHINE_GHCB_H_
 
+#ifdef AMDSEV
+
 #ifndef _LOCORE
 
 #include <sys/systm.h>
@@ -42,6 +44,19 @@
 
 #define GHCB_MAX			0xFFF
 
+#endif	/* !_LOCORE */
+
+/* Definitions used with the MSR protocol */
+#define MSR_PROTO_CPUID_REQ			0x4
+#define MSR_PROTO_CPUID_RESP			0x5
+#define MSR_PROTO_PREFERRED_GHCB_PA_REQ		0x10
+#define MSR_PROTO_PREFERRED_GHCB_PA_RESP	0x11
+#define MSR_PROTO_REGISTER_GHCB_PA_REQ		0x12
+#define MSR_PROTO_REGISTER_GHCB_PA_RESP		0x13
+#define MSR_PROTO_TERMINATION_REQ		0x100
+
+#ifndef _LOCORE
+
 struct ghcb_sa {
 	uint8_t			v_pad0[0xcb];		/* 000h-0CAh */
 	uint8_t			v_cpl;			/* 0CBh */
@@ -102,14 +117,6 @@ struct ghcb_sync {
 	int			sz_c;
 	int			sz_d;
 };
-#endif /* !_LOCORE */
-
-/* Definitions used with the MSR protocol */
-#define MSR_PROTO_CPUID_REQ	0x4
-#define MSR_PROTO_CPUID_RESP	0x5
-#define MSR_PROTO_TERMINATE	0x100
-
-#ifndef _LOCORE
 
 extern vaddr_t ghcb_vaddr;
 extern paddr_t ghcb_paddr;
@@ -249,4 +256,11 @@ ghcb_io_write_4(uint16_t port, uint32_t v)
 
 #endif /* !_LOCORE */
 
+#else	/* !AMDSEV */
+
+/* Definitions used with the MSR protocol */
+#define MSR_PROTO_TERMINATION_REQ		0x100
+
+#endif	/* AMDSEV */
+
 #endif /* !_MACHINE_GHCB_H_ */
-- 
2.53.0