Re: [EXT] Re: SEV-SNP: Prepare for SNP page validation 1/4
Alexander Bluhm <[email protected]>
| Newsgroups | gmane.os.openbsd.tech |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Aug 18, 2026 at 01:22:00PM +0200, Hans-J?rg H?xer wrote:
> 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?
I have built release on host and tested network interfaces on guests
without SEV, with SEV and SEV-ES.
bluhm
>
> 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(®ion);
> }
>
> +#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
>