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);