From: Mike Larkin Subject: Re: SEV-ES: vmm(4): Handle IOIO gexit To: tech@openbsd.org Date: Tue, 20 May 2025 17:52:37 -0700 On Tue, May 20, 2025 at 12:23:11PM +0200, Hans-Jörg Höxer wrote: > Hi, > > and the last chunk, in/out related GEXIT. > > Fill in the actual handler for IOIO related GEXIT: The actual > in/out instruction is encoded in the exitinfo provided by the guest > in the GHCB. For in vmm(4) returns the result in the A GPR. > > The actual emulation is done by svm_handle_inout() and vmd(8). On > the way back into the guest, vmm(4) synchronizes the computed result > back to the GHCB. > > With this diff vmm(8)/vmd(8) will be able to deal with all GEXITs that > will be generated by openbsd SEV-ES enabled guest (for now). > > Take care, > HJ. ok mlarkin > ------------------------------------------------------------------------- > commit 270c450535e0465ede449f02bf11faac624037d8 > Author: Hans-Joerg Hoexer > Date: Wed Jan 22 14:38:33 2025 +0100 > > vmm(4): Handle IOIO gexit > > Fill in the actual handler for IOIO related GEXIT: The actual > in/out instruction is encoded in the exitinfo provided by the guest > in the GHCB. For in vmm(4) returns the result in the A GPR. > > The actual emulation is done by svm_handle_inout() and vmd(8). On > the way back into the guest, vmm(4) synchronizes the computed result > back to the GHCB. > > diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c > index 9bcf3f3fffe..9049bc6340d 100644 > --- a/sys/arch/amd64/amd64/vmm_machdep.c > +++ b/sys/arch/amd64/amd64/vmm_machdep.c > @@ -4393,6 +4393,14 @@ svm_gexit_sync_host(struct vcpu *vcpu) > ghcb_valbm_set(expected_bm, GHCB_RCX); > } > break; > + case SVM_VMEXIT_IOIO: > + if (ghcb->v_sw_exitinfo1 & 0x1) { > + /* in instruction, no registers used */ > + } else { > + /* out instruction */ > + ghcb_valbm_set(expected_bm, GHCB_RAX); > + } > + break; > default: > return (EINVAL); > } > @@ -4458,6 +4466,14 @@ svm_gexit_sync_guest(struct vcpu *vcpu) > ghcb_valbm_set(valid_bm, GHCB_RDX); > } > break; > + case SVM_VMEXIT_IOIO: > + if (svm_sw_exitinfo1 & 0x1) { > + /* IN */ > + ghcb_valbm_set(valid_bm, GHCB_RAX); > + } else { > + /* OUT -- nothing to return */ > + } > + break; > default: > return (EINVAL); > } > @@ -4523,6 +4539,10 @@ svm_handle_gexit(struct vcpu *vcpu) > vcpu->vc_gueststate.vg_rax = vmcb->v_rax; > syncout = 1; > break; > + case SVM_VMEXIT_IOIO: > + if (svm_handle_inout(vcpu) == 0) > + error = EAGAIN; > + break; > case SVM_VMEXIT_MSR: > error = svm_handle_msr(vcpu); > vmcb->v_rip = vcpu->vc_gueststate.vg_rip; > @@ -6468,6 +6488,8 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp) > vcpu->vc_gueststate.vg_rip = > vcpu->vc_exit.vrs.vrs_gprs[VCPU_REGS_RIP]; > vmcb->v_rip = vcpu->vc_gueststate.vg_rip; > + if (svm_gexit_sync_guest(vcpu)) > + return (EINVAL); > break; > case SVM_VMEXIT_NPF: > ret = vcpu_writeregs_svm(vcpu, VM_RWREGS_GPRS,