Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
Re: [EXT] Re: SEV-SNP: Prepare for SNP page validation 1/4
To:
Hans-Jörg Höxer <hshoexer@genua.de>
Cc:
tech@openbsd.org, Hans-Joerg_Hoexer@genua.de
Date:
Tue, 18 Aug 2026 14:05:58 +0200

Download raw body.

Thread
  • Mike Larkin:

    SEV-SNP: Prepare for SNP page validation 1/4

  • > Date: Tue, 18 Aug 2026 13:22:00 +0200
    > From: Hans-Jörg Höxer <hshoexer@genua.de>
    > 
    > 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?
    
    looks good to me
    
    > 
    > 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
    > 
    > 
    > [2:application/pkcs7-signature Show Save:smime.p7s (6kB)]
    > 
    
    
  • Mike Larkin:

    SEV-SNP: Prepare for SNP page validation 1/4