diff --git a/repos/ports/lib/mk/virtualbox-common.inc b/repos/ports/lib/mk/virtualbox-common.inc
index a3c1d134ad..bf79c3e4c7 100644
--- a/repos/ports/lib/mk/virtualbox-common.inc
+++ b/repos/ports/lib/mk/virtualbox-common.inc
@@ -73,6 +73,8 @@ VBOX_CC_OPT += -DVBOX_WITH_VMSVGA
VBOX_CC_OPT += -DVBOX_HDD_NO_DYNAMIC_BACKENDS
+VBOX_CC_OPT += -DVBOX_WITHOUT_NS_ACCOUNTING
+
CC_WARN += -Wno-trigraphs
CC_OPT += $(VBOX_CC_OPT)
diff --git a/repos/ports/lib/mk/virtualbox5-common.inc b/repos/ports/lib/mk/virtualbox5-common.inc
index 0655da5ae7..afa1758cfc 100644
--- a/repos/ports/lib/mk/virtualbox5-common.inc
+++ b/repos/ports/lib/mk/virtualbox5-common.inc
@@ -76,6 +76,8 @@ VBOX_CC_OPT += -DVBOX_WITH_VMSVGA
VBOX_CC_OPT += -DVBOX_HDD_NO_DYNAMIC_BACKENDS
+VBOX_CC_OPT += -DVBOX_WITHOUT_NS_ACCOUNTING
+
CC_WARN += -Wno-trigraphs
CC_OPT += $(VBOX_CC_OPT)
diff --git a/repos/ports/ports/virtualbox.hash b/repos/ports/ports/virtualbox.hash
index 52d5379d1b..2f84683fe7 100644
--- a/repos/ports/ports/virtualbox.hash
+++ b/repos/ports/ports/virtualbox.hash
@@ -1 +1 @@
-9d1982f1082108c0dc28855956f61752c6526b1d
+38087cad05854ea953885c3c7187dc25d323140e
diff --git a/repos/ports/ports/virtualbox5.hash b/repos/ports/ports/virtualbox5.hash
index 5f24451fff..8fa2f98c9e 100644
--- a/repos/ports/ports/virtualbox5.hash
+++ b/repos/ports/ports/virtualbox5.hash
@@ -1 +1 @@
-558507616b26c82ad984d7e4251c7f08131b0da8
+f22cfd50576d6821473e202a8a3fc973a9f808d4
diff --git a/repos/ports/run/vm_win7_64.vbox b/repos/ports/run/vm_win7_64.vbox
index 1acd54568e..2d99f23d33 100644
--- a/repos/ports/run/vm_win7_64.vbox
+++ b/repos/ports/run/vm_win7_64.vbox
@@ -21,7 +21,7 @@
-
+
diff --git a/repos/ports/src/virtualbox/patches/series_common b/repos/ports/src/virtualbox/patches/series_common
index b691428249..450ff03015 100644
--- a/repos/ports/src/virtualbox/patches/series_common
+++ b/repos/ports/src/virtualbox/patches/series_common
@@ -14,3 +14,4 @@ sharedfolder_pagelist.patch
time-log-deadlock.patch
tm_retries.patch
vmdk.patch
+tm_tpr.patch
diff --git a/repos/ports/src/virtualbox/patches/tm_tpr.patch b/repos/ports/src/virtualbox/patches/tm_tpr.patch
new file mode 100644
index 0000000000..9ff15c5f10
--- /dev/null
+++ b/repos/ports/src/virtualbox/patches/tm_tpr.patch
@@ -0,0 +1,43 @@
+--- a/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp
++++ b/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp
+@@ -1934,6 +1947,7 @@
+ *
+ * @thread EMT (actually EMT0, but we fend off the others)
+ */
++#include
+ VMMR3DECL(void) TMR3TimerQueuesDo(PVM pVM)
+ {
+ /*
+@@ -1947,6 +1961,32 @@
+ Assert(pVM->cCpus > 1);
+ return;
+ }
++
++ /*
++ * It may happen that a EMT thread has an inconsistent IRQ state
++ * (Why the hell XXX ? - SMP 64bit Win7 - especially during early bootup).
++ * Poke the EMT threads so that they may get back to VMM and update
++ * and synchronize IRQ state in recall handler. This code may issue to
++ * often a POKE, since we check state of concurrently running EMT threads!
++ */
++ for (unsigned i = 0; i < pVM->cCpus; i++) {
++ if (i == pVCpuDst->idCpu)
++ continue;
++
++ bool interrupt_pending = false;
++ uint8_t tpr = 0;
++ uint8_t pending_interrupt;
++ PDMApicGetTPR(&pVM->aCpus[i], &tpr, &interrupt_pending, &pending_interrupt);
++
++ asm volatile ("":::"memory");
++ if ((VMCPU_GET_STATE(&pVM->aCpus[i]) == VMCPUSTATE_STARTED_EXEC)
++ && !TRPMHasTrap(&pVM->aCpus[i])
++ && !VMCPU_FF_IS_PENDING(&pVM->aCpus[i], (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
++ && interrupt_pending) {
++ SUPR3CallVMMR0Ex(pVM->pVMR0, i, VMMR0_DO_GVMM_SCHED_POKE, 0, NULL);
++ }
++ }
++
+ STAM_PROFILE_START(&pVM->tm.s.StatDoQueues, a);
+ Log2(("TMR3TimerQueuesDo:\n"));
+ Assert(!pVM->tm.s.fRunningQueues);
diff --git a/repos/ports/src/virtualbox/spec/nova/vcpu.h b/repos/ports/src/virtualbox/spec/nova/vcpu.h
index d967b858c0..4f85c81e97 100644
--- a/repos/ports/src/virtualbox/spec/nova/vcpu.h
+++ b/repos/ports/src/virtualbox/spec/nova/vcpu.h
@@ -199,9 +199,23 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
Nova::reply(_stack_reply);
}
- /* nothing to do at all - continue hardware accelerated */
+ unsigned long utcb_tpr = utcb->read_tpr();
+ bool interrupt_pending = false;
+ uint8_t tpr = 0;
+ uint8_t pending_interrupt = 0;
+ PDMApicGetTPR(_current_vcpu, &tpr, &interrupt_pending, &pending_interrupt);
- Assert(!_irq_win);
+ /* we have a pending interrupt but nothing should be requested ? */
+ if (interrupt_pending) {
+ PDMApicSetTPR(_current_vcpu, utcb_tpr);
+
+ utcb->mtd = Nova::Mtd::FPU;
+ _irq_win = check_to_request_irq_window(utcb, _current_vcpu);
+ if (_irq_win)
+ Nova::reply(_stack_reply);
+ }
+
+ /* nothing to do at all - continue hardware accelerated */
/*
* Print a debug message if there actually IS something to do now.
@@ -210,8 +224,15 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
* by a recall request, but we haven't verified this for each flag
* yet.
*/
+ utcb->mtd = Nova::Mtd::FPU;
continue_hw_accelerated(utcb, true);
+ if (_irq_win) {
+ _irq_win = false;
+ utcb->inj_info = IRQ_INJ_NONE;
+ utcb->mtd |= Nova::Mtd::INJ;
+ }
+
Nova::reply(_stack_reply);
}
@@ -515,6 +536,20 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
const uint32_t tpr = utcb->read_tpr();
+ /* reset message transfer descriptor for next invocation */
+ Assert (!(utcb->inj_info & IRQ_INJ_VALID_MASK));
+ /* Reset irq window next time if we are still requesting it */
+ next_utcb.mtd = _irq_win ? Nova::Mtd::INJ : 0;
+
+ next_utcb.intr_state = utcb->intr_state;
+ next_utcb.ctrl[0] = utcb->ctrl[0];
+ next_utcb.ctrl[1] = utcb->ctrl[1];
+
+ if (next_utcb.intr_state & 3) {
+ next_utcb.intr_state &= ~3U;
+ next_utcb.mtd |= Nova::Mtd::STA;
+ }
+
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
/* tell rem compiler that FPU register changed XXX optimizations ? */
@@ -571,7 +606,6 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
PDMApicSetTPR(pVCpu, utcb->read_tpr());
if (!TRPMHasTrap(pVCpu)) {
-
bool res = VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI);
Assert(!res);
@@ -847,20 +881,6 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
return VERR_INTERNAL_ERROR;
}
- /* reset message transfer descriptor for next invocation */
- Assert (!(utcb->inj_info & IRQ_INJ_VALID_MASK));
- /* Reset irq window next time if we are still requesting it */
- next_utcb.mtd = _irq_win ? Mtd::INJ : 0;
-
- next_utcb.intr_state = utcb->intr_state;
- next_utcb.ctrl[0] = utcb->ctrl[0];
- next_utcb.ctrl[1] = utcb->ctrl[1];
-
- if (next_utcb.intr_state & 3) {
- next_utcb.intr_state &= ~3U;
- next_utcb.mtd |= Mtd::STA;
- }
-
#ifdef VBOX_WITH_REM
/* XXX see VMM/VMMR0/HMVMXR0.cpp - not necessary every time ! XXX */
REMFlushTBs(pVM);
diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu.h b/repos/ports/src/virtualbox5/spec/nova/vcpu.h
index 82fe6d62f5..2c0903e44f 100644
--- a/repos/ports/src/virtualbox5/spec/nova/vcpu.h
+++ b/repos/ports/src/virtualbox5/spec/nova/vcpu.h
@@ -206,9 +206,23 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
Nova::reply(_stack_reply);
}
- /* nothing to do at all - continue hardware accelerated */
+ unsigned long utcb_tpr = utcb->read_tpr();
+ bool interrupt_pending = false;
+ uint8_t tpr = 0;
+ uint8_t pending_interrupt = 0;
+ PDMApicGetTPR(_current_vcpu, &tpr, &interrupt_pending, &pending_interrupt);
- Assert(!_irq_win);
+ /* we have a pending interrupt but nothing should be requested ? */
+ if (interrupt_pending) {
+ PDMApicSetTPR(_current_vcpu, utcb_tpr);
+
+ utcb->mtd = Nova::Mtd::FPU;
+ _irq_win = check_to_request_irq_window(utcb, _current_vcpu);
+ if (_irq_win)
+ Nova::reply(_stack_reply);
+ }
+
+ /* nothing to do at all - continue hardware accelerated */
/*
* Print a debug message if there actually IS something to do now.
@@ -217,8 +231,15 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
* by a recall request, but we haven't verified this for each flag
* yet.
*/
+ utcb->mtd = Nova::Mtd::FPU;
continue_hw_accelerated(utcb, true);
+ if (_irq_win) {
+ _irq_win = false;
+ utcb->inj_info = IRQ_INJ_NONE;
+ utcb->mtd |= Nova::Mtd::INJ;
+ }
+
Nova::reply(_stack_reply);
}
@@ -518,6 +539,20 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
const uint32_t tpr = utcb->read_tpr();
+ /* reset message transfer descriptor for next invocation */
+ Assert (!(utcb->inj_info & IRQ_INJ_VALID_MASK));
+ /* Reset irq window next time if we are still requesting it */
+ next_utcb.mtd = _irq_win ? Nova::Mtd::INJ : 0;
+
+ next_utcb.intr_state = utcb->intr_state;
+ next_utcb.ctrl[0] = utcb->ctrl[0];
+ next_utcb.ctrl[1] = utcb->ctrl[1];
+
+ if (next_utcb.intr_state & 3) {
+ next_utcb.intr_state &= ~3U;
+ next_utcb.mtd |= Nova::Mtd::STA;
+ }
+
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
/* tell rem compiler that FPU register changed XXX optimizations ? */
@@ -856,20 +891,6 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher,
return VERR_INTERNAL_ERROR;
}
- /* reset message transfer descriptor for next invocation */
- Assert (!(utcb->inj_info & IRQ_INJ_VALID_MASK));
- /* Reset irq window next time if we are still requesting it */
- next_utcb.mtd = _irq_win ? Mtd::INJ : 0;
-
- next_utcb.intr_state = utcb->intr_state;
- next_utcb.ctrl[0] = utcb->ctrl[0];
- next_utcb.ctrl[1] = utcb->ctrl[1];
-
- if (next_utcb.intr_state & 3) {
- next_utcb.intr_state &= ~3U;
- next_utcb.mtd |= Mtd::STA;
- }
-
#ifdef VBOX_WITH_REM
/* XXX see VMM/VMMR0/HMVMXR0.cpp - not necessary every time ! XXX */
REMFlushTBs(pVM);