Index | Thread | Search

From:
Hans-Jörg Höxer <hshoexer@genua.de>
Subject:
Re: [EXT] Re: SEV-ES: vmm(4): GHCB MSR protocol for CPUID
To:
<tech@openbsd.org>
Date:
Wed, 21 May 2025 12:13:08 +0200

Download raw body.

Thread
Hi,

On Tue, May 20, 2025 at 05:58:45PM -0700, Mike Larkin wrote:
> On Tue, May 20, 2025 at 02:05:28PM +0200, Hans-Jörg Höxer wrote:
> > Hi,
> >
> > my last two diffs for vmm(4) and SEV-ES:
> >
> >     When a SEV-ES guest is in locore, it will not be able yet to use a
> >     GHCB to communicate with vmm(4).  Therefore, AMD specifies a "GHCB
> >     MSR protocol" that uses the lowere 12 bits of the GHCB MSR to request
> >     services from vmm(4).  Guest writes to the GHCB MSR will show up in
> >     the v_ghcb_gpa member of the VMCB and are thus accesible by vmm(4).
> >     The response of vmm(4) can be provided by writing it to the VMCB.
> >
> >     In locore a SEV-ES guest will need to request CPUID from vmm(4)
> >     using the GHCB MSR protocol.  This diff provides this service.
> >
> > Take care,
> > HJ.
> >
> 
> Diff looks ok; one question though. Is the locore side of this diff still
> coming or did that already go in? Eg, is there a corresponding change for
> the guest to use the GHCB MSR protocol?

the locore side is coming soon.  Later today, I think.  Hang on :)

> ok mlarkin in any case.

thanks!

> > ---------------------------------------------------------------------------
> > commit 8278f4051b90ee94e19db25d019100a736ee7317
> > Author: Hans-Joerg Hoexer <hshoexer@genua.de>
> > Date:   Mon Nov 18 13:59:19 2024 +0100
> >
> >     vmm(4): GHCB MSR protocol for CPUID
> >
> >     When a SEV-ES guest is in locore, it will not be able yet to use a
> >     GHCB to communicate with vmm(4).  Therefore, AMD specifies a "GHCB
> >     MSR protocol" that uses the lowere 12 bits of the GHCB MSR to request
> >     services from vmm(4).  Guest writes to the GHCB MSR will show up in
> >     the v_ghcb_gpa member of the VMCB and are thus accesible by vmm(4).
> >     The response of vmm(4) can be provided by writing it to the VMCB.
> >
> >     In locore a SEV-ES guest will need to request CPUID from vmm(4)
> >     using the GHCB MSR protocol.  This diff provides this service.
> >
> > diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c
> > index 9049bc6340d..2e90b7340f2 100644
> > --- a/sys/arch/amd64/amd64/vmm_machdep.c
> > +++ b/sys/arch/amd64/amd64/vmm_machdep.c
> > @@ -4514,13 +4514,67 @@ svm_handle_gexit(struct vcpu *vcpu)
> >  	struct vm		*vm = vcpu->vc_parent;
> >  	struct ghcb_sa		*ghcb;
> >  	paddr_t			 ghcb_gpa, ghcb_hpa;
> > +	uint32_t		 req, resp;
> > +	uint64_t		 result;
> >  	int			 syncout, error = 0;
> >
> > -	if (vcpu->vc_svm_ghcb_va == 0) {
> > +	if (vcpu->vc_svm_ghcb_va == 0 && (vmcb->v_ghcb_gpa & ~PG_FRAME) == 0 &&
> > +	    (vmcb->v_ghcb_gpa & PG_FRAME) != 0) {
> > +		/*
> > +		 * Guest provides a valid guest physcial address
> > +		 * for GHCB and it is not set yet -> assign it.
> > +		 *
> > +		 * We only accept a GHCB once; we decline re-definition.
> > +		 */
> >  		ghcb_gpa = vmcb->v_ghcb_gpa & PG_FRAME;
> >  		if (!pmap_extract(vm->vm_map->pmap, ghcb_gpa, &ghcb_hpa))
> >  			return (EINVAL);
> >  		vcpu->vc_svm_ghcb_va = (vaddr_t)PMAP_DIRECT_MAP(ghcb_hpa);
> > +	} else if ((vmcb->v_ghcb_gpa & ~PG_FRAME) != 0) {
> > +		/*
> > +                 * Low bits in use, thus must be a MSR protocol
> > +		 * request.
> > +		 */
> > +		req = (vmcb->v_ghcb_gpa & 0xffffffff);
> > +
> > +		/* we only support cpuid */
> > +		if ((req & ~PG_FRAME) != MSR_PROTO_CPUID_REQ)
> > +			return (EINVAL);
> > +
> > +		/* Emulate CPUID */
> > +		vmcb->v_exitcode = SVM_VMEXIT_CPUID;
> > +		vmcb->v_rax = vmcb->v_ghcb_gpa >> 32;
> > +		vcpu->vc_gueststate.vg_rax = 0;
> > +		vcpu->vc_gueststate.vg_rbx = 0;
> > +		vcpu->vc_gueststate.vg_rcx = 0;
> > +		vcpu->vc_gueststate.vg_rdx = 0;
> > +		error = vmm_handle_cpuid(vcpu);
> > +		if (error)
> > +			goto out;
> > +
> > +		switch (req >> 30) {
> > +		case 0:	/* eax: emulate cpuid and return eax */
> > +			result = vmcb->v_rax;
> > +			break;
> > +		case 1:	/* return ebx */
> > +			result = vcpu->vc_gueststate.vg_rbx;
> > +			break;
> > +		case 2: /* return ecx */
> > +			result = vcpu->vc_gueststate.vg_rcx;
> > +			break;
> > +		case 3:	/* return edx */
> > +			result = vcpu->vc_gueststate.vg_rdx;
> > +			break;
> > +		default:
> > +			DPRINTF("%s: unknown request 0x%x\n", __func__, req);
> > +			return (EINVAL);
> > +		}
> > +
> > +		/* build response */
> > +		resp = MSR_PROTO_CPUID_RESP | (req & 0xc0000000);
> > +		vmcb->v_ghcb_gpa = (result << 32) | resp;
> > +
> > +		return (0);
> >  	}
> >
> >  	/* Verify GHCB and synchronize guest state information. */
> > diff --git a/sys/arch/amd64/include/ghcb.h b/sys/arch/amd64/include/ghcb.h
> > index 802bf7f015e..954e1fa3e3b 100644
> > --- a/sys/arch/amd64/include/ghcb.h
> > +++ b/sys/arch/amd64/include/ghcb.h
> > @@ -101,6 +101,12 @@ struct ghcb_sync {
> >  };
> >
> >
> > +/* Definitions used with the MSR protocol */
> > +#define MSR_PROTO_CPUID_REQ	0x4
> > +#define MSR_PROTO_CPUID_RESP	0x5
> > +#define MSR_PROTO_TERMINATE	0x100
> > +
> > +
> >  void	ghcb_clear(struct ghcb_sa *);
> >  int	ghcb_valbm_set(uint8_t *, int);
> >  int	ghcb_valbm_isset(uint8_t *, int);
> 
> 

-- 
Dr. Hans-Jörg Höxer                   Hans-Joerg_Hoexer@genua.de
Senior Expert Kryptographie
eXtreme Kernel and Crypto Development

genua GmbH
Domagkstrasse 7, 85551 Kirchheim bei München
tel +49 89 991950-0, fax -999, www.genua.eu

Geschäftsführer: Matthias Ochs, Marc Tesch
Amtsgericht München HRB 98238
genua ist ein Unternehmen der Bundesdruckerei-Gruppe.