Page MenuHomeFreeBSD
Paste P342

Masterwork From Distant Lands
ActivePublic

Authored by markj on Dec 10 2019, 7:50 PM.
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..bdc551a11be0 100644
--- a/sys/amd64/vmm/intel/vmx_support.S
+++ b/sys/amd64/vmm/intel/vmx_support.S
@@ -325,8 +325,8 @@ ENTRY(vmx_call_isr)
pushq %r11 /* %rsp */
pushfq /* %rflags */
pushq $KERNEL_CS /* %cs */
- cli /* disable interrupts */
callq *%rdi /* push %rip and call isr */
+ sti
VLEAVE
ret
END(vmx_call_isr)

Event Timeline

markj edited the content of this paste. (Show Details)Dec 10 2019, 7:50 PM
markj changed the title of this paste from untitled to Masterwork From Distant Lands.