Download raw body.
SEV-ES: vmm(4): Handle IOIO gexit
Hi,
updated diff addressing name tweak svm_gexit_sync_guest() to
svm_vmgexit_sync_guest() (last diff chunk). Otherwise no change.
Take care,
HJ.
----------------------------------------------------------------------
commit a2d66c5c2c3a1c9339c5c583cda088d64513f20c
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 a8cc195c78f..76cdaf4f74e 100644
--- a/sys/arch/amd64/amd64/vmm_machdep.c
+++ b/sys/arch/amd64/amd64/vmm_machdep.c
@@ -4359,6 +4359,14 @@ svm_vmgexit_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);
}
@@ -4424,6 +4432,14 @@ svm_vmgexit_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);
}
@@ -4489,6 +4505,10 @@ svm_handle_vmgexit(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;
@@ -6515,6 +6535,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_vmgexit_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