diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 7bc9fdce8743..241affd06af9 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -2258,6 +2258,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) */ if (__predict_false(reason == EXIT_REASON_MCE_DURING_ENTRY)) { VCPU_CTR0(vmx->vm, vcpu, "Handling MCE during VM-entry"); + enable_intr(); __asm __volatile("int $18"); return (1); } @@ -2312,6 +2313,42 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) } } + if (reason == EXIT_REASON_EXT_INTR) { + /* + * External interrupts serve only to cause VM exits and allow + * the host interrupt handler to run. + * + * If this external interrupt triggers a virtual interrupt + * to a VM, then that state will be recorded by the + * host interrupt handler in the VM's softc. We will inject + * this virtual interrupt during the subsequent VM enter. + */ + intr_info = vmcs_read(VMCS_EXIT_INTR_INFO); + SDT_PROBE4(vmm, vmx, exit, interrupt, + vmx, vcpu, vmexit, intr_info); + + /* + * XXX: Ignore this exit if VMCS_INTR_VALID is not set. + * This appears to be a bug in VMware Fusion? + */ + if (!(intr_info & VMCS_INTR_VALID)) { + enable_intr(); + return (1); + } + KASSERT((intr_info & VMCS_INTR_VALID) != 0 && + (intr_info & VMCS_INTR_T_MASK) == VMCS_INTR_T_HWINTR, + ("VM exit interruption info invalid: %#x", intr_info)); + vmx_trigger_hostintr(intr_info & 0xff); + + /* + * This is special. We want to treat this as an 'handled' + * VM-exit but not increment the instruction pointer. + */ + vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EXTINT, 1); + return (1); + } + enable_intr(); + switch (reason) { case EXIT_REASON_TASK_SWITCH: ts = &vmexit->u.task_switch; @@ -2441,37 +2478,6 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) SDT_PROBE3(vmm, vmx, exit, intrwindow, vmx, vcpu, vmexit); vmx_clear_int_window_exiting(vmx, vcpu); return (1); - case EXIT_REASON_EXT_INTR: - /* - * External interrupts serve only to cause VM exits and allow - * the host interrupt handler to run. - * - * If this external interrupt triggers a virtual interrupt - * to a VM, then that state will be recorded by the - * host interrupt handler in the VM's softc. We will inject - * this virtual interrupt during the subsequent VM enter. - */ - intr_info = vmcs_read(VMCS_EXIT_INTR_INFO); - SDT_PROBE4(vmm, vmx, exit, interrupt, - vmx, vcpu, vmexit, intr_info); - - /* - * XXX: Ignore this exit if VMCS_INTR_VALID is not set. - * This appears to be a bug in VMware Fusion? - */ - if (!(intr_info & VMCS_INTR_VALID)) - return (1); - KASSERT((intr_info & VMCS_INTR_VALID) != 0 && - (intr_info & VMCS_INTR_T_MASK) == VMCS_INTR_T_HWINTR, - ("VM exit interruption info invalid: %#x", intr_info)); - vmx_trigger_hostintr(intr_info & 0xff); - - /* - * This is special. We want to treat this as an 'handled' - * VM-exit but not increment the instruction pointer. - */ - vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EXTINT, 1); - return (1); case EXIT_REASON_NMI_WINDOW: SDT_PROBE3(vmm, vmx, exit, nmiwindow, vmx, vcpu, vmexit); /* Exit to allow the pending virtual NMI to be injected */ @@ -2966,7 +2972,6 @@ vmx_run(void *arg, int vcpu, register_t rip, pmap_t pmap, if (rc == VMX_GUEST_VMEXIT) { vmx_exit_handle_nmi(vmx, vcpu, vmexit); - enable_intr(); handled = vmx_exit_process(vmx, vcpu, vmexit); } else { enable_intr(); diff --git a/sys/amd64/vmm/intel/vmx_support.S b/sys/amd64/vmm/intel/vmx_support.S index 1652abac2134..23a268c10ad9 100644 --- a/sys/amd64/vmm/intel/vmx_support.S +++ b/sys/amd64/vmm/intel/vmx_support.S @@ -325,7 +325,7 @@ ENTRY(vmx_call_isr) pushq %r11 /* %rsp */ pushfq /* %rflags */ pushq $KERNEL_CS /* %cs */ - cli /* disable interrupts */ + //cli /* disable interrupts */ callq *%rdi /* push %rip and call isr */ VLEAVE ret