vmm.c: struct hw_exception { int vector; int error_valid; uint32_t errcode; }; int vm_inject_exception(struct vm *vm, int vcpuid, struct hw_exception *hwe) { struct vcpu *vcpu = &vm->vcpu[vcpuid]; if (vcpu->hwe_pending) return (EBUSY); vcpu->hwe_pending = 1; vcpu->hwe.vector = hwe->vector; vcpu->hwe.errcode = hwe->errcode; vcpu->hwe.errcode_valid = hwe->errcode_valid; return (0); } int vm_exception_pending(struct vm *vm, int vcpuid, struct hw_exception *hwe) { struct vcpu *vcpu = &vm->vcpu[vcpuid]; int pending; if ((pending = vcpu->hwe_pending) != 0) { vcpu->hwe_pending = 0; bcopy(&vcpu->hwe, hwe, sizeof(*hwe)); } return (pending); } static void vm_inject_fault(struct vm *vm, int vcpuid, struct hw_exception *hwe) { struct vm_exit *vmexit; int error; error = vm_inject_exception(vm, vcpuid, hwe); KASSERT(error == 0, ("could not inject exception")); vmexit = vm_exitinfo(vm, vcpuid); vmexit->inst_length = 0; } void vm_inject_gp(struct vm *vm, int vcpuid) { struct hw_exception hwe = { IDT_GP, 1, 0 }; vm_inject_fault(vm, vcpuid, &hwe); } void vm_inject_ud(struct vm *vm, int vcpuid) { struct hw_exception hwe = { IDT_UD, 0, 0 }; vm_inject_fault(vm, vcpuid, &hwe); } vmm_dev.c: /* * XXX practically this now becomes VM_INJECT_HW_EXCEPTION so we * might as well change the ioctl name. */ case VM_INJECT_EVENT: hwe.vector = vmevent->vector; hwe.errcode = vmevent->errcode; hwe.errcode_valid = vmevent->errcode_valid; error = vm_inject_exception(vm, vcpuid, &hwe); break; vmx.c: vmx_inject_interrupts() { struct hw_exception hwe; int pending; if (vm_exception_pending(vmx->vm, vcpuid, &hwe)) { info = vmcs_read(VMCS_ENTRY_INTR_INFO); KASSERT((info & VMCS_INTR_VALID) == 0, ("cannot inject pending exception")); info = hwe.vector | VMCS_INTR_T_HWEXCEPTION | VMCS_INTR_VALID; if (hwe.error_valid) { info |= VMCS_INTR_DEL_ERRCODE; vmcs_write(VMCS_ENTRY_EXCEPTION_ERROR, hwe.errcode); } vmcs_write(VMCS_ENTRY_INTR_INFO, info); } /* NMI delivery if possible */ /* Interrupt delivery if possible */ } The following functions can now go away: - vm_inject_event() - VMINJECT() - vmx_inject() - svm_inject()