Download raw body.
SEV-ES: vmm(4): Handle IOIO gexit
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 <hshoexer@genua.de>
> 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,
SEV-ES: vmm(4): Handle IOIO gexit