Index | Thread | Search

From:
Mike Larkin <mlarkin@nested.page>
Subject:
Re: SEV-ES guest: locore #VC trap handling
To:
Alexander Bluhm <alexander.bluhm@gmx.net>
Cc:
tech@openbsd.org
Date:
Mon, 23 Jun 2025 09:34:13 -0700

Download raw body.

Thread
  • Alexander Bluhm:

    SEV-ES guest: locore #VC trap handling

    • Mike Larkin:

      SEV-ES guest: locore #VC trap handling

  • 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 <hshoexer@genua.de>
    > > 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);
    
    
  • Alexander Bluhm:

    SEV-ES guest: locore #VC trap handling