From: Mike Larkin Subject: Re: SEV-ES guest: locore #VC trap handling To: Alexander Bluhm Cc: tech@openbsd.org Date: Mon, 23 Jun 2025 09:34:13 -0700 On Mon, Jun 23, 2025 at 02:52:22PM +0200, Alexander Bluhm wrote: > Hi Mike, > > I have commited the locore0 guest part of the #VC trap handler. > Let's see if there is any fallout. > > The part below for vmd(8) is still missing. Can you have a look? > looks fine. ok mlarkin > bluhm > > On Wed, May 21, 2025 at 05:10:27PM +0200, Hans-J?rg H?xer wrote: > > commit c29b30056940a3f8b2acfd18b734daf60257656a > > Author: Hans-Joerg Hoexer > > Date: Wed Nov 20 11:16:48 2024 +0100 > > > > vmd(8): Setup long mode code segment for SEV-ES guests > > > > Right now vmd(8) starts a kernel image in compatibility mode. > > However, SEV-ES enabled guest will trigger #VC traps during locore. > > To be able to run such a trap handler, we need a long mode segment. > > > > diff --git a/usr.sbin/vmd/loadfile_elf.c b/usr.sbin/vmd/loadfile_elf.c > > index 2b62ca07565..73c2010397d 100644 > > --- a/usr.sbin/vmd/loadfile_elf.c > > +++ b/usr.sbin/vmd/loadfile_elf.c > > @@ -110,7 +110,7 @@ union { > > } hdr; > > > > static void setsegment(struct mem_segment_descriptor *, uint32_t, > > - size_t, int, int, int, int); > > + size_t, int, int, int, int, int); > > static int elf32_exec(gzFile, Elf32_Ehdr *, u_long *, int); > > static int elf64_exec(gzFile, Elf64_Ehdr *, u_long *, int); > > static size_t create_bios_memmap(struct vm_create_params *, bios_memmap_t *); > > @@ -148,7 +148,7 @@ uint64_t pg_crypt = 0; > > */ > > static void > > setsegment(struct mem_segment_descriptor *sd, uint32_t base, size_t limit, > > - int type, int dpl, int def32, int gran) > > + int type, int dpl, int def32, int gran, int lm) > > { > > sd->sd_lolimit = (int)limit; > > sd->sd_lobase = (int)base; > > @@ -157,7 +157,7 @@ setsegment(struct mem_segment_descriptor *sd, uint32_t base, size_t limit, > > sd->sd_p = 1; > > sd->sd_hilimit = (int)limit >> 16; > > sd->sd_avl = 0; > > - sd->sd_long = 0; > > + sd->sd_long = lm; > > sd->sd_def32 = def32; > > sd->sd_gran = gran; > > sd->sd_hibase = (int)base >> 24; > > @@ -185,11 +185,13 @@ push_gdt(void) > > * Create three segment descriptors: > > * > > * GDT[0] : null descriptor. "Created" via memset above. > > - * GDT[1] (selector @ 0x8): Executable segment, for CS > > + * GDT[1] (selector @ 0x8): Executable segment (compat mode), for CS > > * GDT[2] (selector @ 0x10): RW Data segment, for DS/ES/SS > > + * GDT[3] (selector @ 0x18): Executable segment (long mode), for CS > > */ > > - setsegment(&sd[1], 0, 0xffffffff, SDT_MEMERA, SEL_KPL, 1, 1); > > - setsegment(&sd[2], 0, 0xffffffff, SDT_MEMRWA, SEL_KPL, 1, 1); > > + setsegment(&sd[1], 0, 0xffffffff, SDT_MEMERA, SEL_KPL, 1, 1, 0); > > + setsegment(&sd[2], 0, 0xffffffff, SDT_MEMRWA, SEL_KPL, 1, 1, 0); > > + setsegment(&sd[3], 0, 0xffffffff, SDT_MEMERA, SEL_KPL, 0, 1, 1); > > > > write_mem(GDT_PAGE, gdtpage, PAGE_SIZE); > > sev_register_encryption(GDT_PAGE, PAGE_SIZE);