From: Hans-Jörg Höxer Subject: Re: [EXT] Re: SEV-ES: vmm(4): GHCB MSR protocol for CPUID To: Date: Wed, 21 May 2025 12:13:08 +0200 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 > > 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.