diff --git a/repos/ports/ports/virtualbox.hash b/repos/ports/ports/virtualbox.hash index 9e9dd27f54..52d5379d1b 100644 --- a/repos/ports/ports/virtualbox.hash +++ b/repos/ports/ports/virtualbox.hash @@ -1 +1 @@ -9739dad12e66d0ac8a900e3c915ea34a1fea1c2b +9d1982f1082108c0dc28855956f61752c6526b1d diff --git a/repos/ports/ports/virtualbox5.hash b/repos/ports/ports/virtualbox5.hash index 91c6690c0e..5f24451fff 100644 --- a/repos/ports/ports/virtualbox5.hash +++ b/repos/ports/ports/virtualbox5.hash @@ -1 +1 @@ -6f6c20213ce4f96218cd69665d2c1757cebbf269 +558507616b26c82ad984d7e4251c7f08131b0da8 diff --git a/repos/ports/src/virtualbox/patches/series b/repos/ports/src/virtualbox/patches/series index 3b95d9169e..a98c5b8df5 100644 --- a/repos/ports/src/virtualbox/patches/series +++ b/repos/ports/src/virtualbox/patches/series @@ -6,7 +6,6 @@ vga_fb.patch vga_vbva.patch vmmdev.patch usb.patch -tm_smp.patch vbox_dd.patch force_ioapic.patch vbox-cpuhotplug.dsl.patch diff --git a/repos/ports/src/virtualbox/patches/tm_smp.patch b/repos/ports/src/virtualbox/patches/tm_smp.patch deleted file mode 100644 index 6e8edb6423..0000000000 --- a/repos/ports/src/virtualbox/patches/tm_smp.patch +++ /dev/null @@ -1,36 +0,0 @@ -tm_smp.patch - -diff --git a/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp b/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp -index c3bc22d..33d705c 100644 ---- a/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp -+++ b/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp -@@ -210,7 +210,7 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM) - pVM->tm.s.paTimerQueuesRC = MMHyperR3ToRC(pVM, pv); - - pVM->tm.s.offVM = RT_OFFSETOF(VM, tm.s); -- pVM->tm.s.idTimerCpu = pVM->cCpus - 1; /* The last CPU. */ -+ pVM->tm.s.idTimerCpu = 0; /* The first CPU. */ - pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].enmClock = TMCLOCK_VIRTUAL; - pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].u64Expire = INT64_MAX; - pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].enmClock = TMCLOCK_VIRTUAL_SYNC; -@@ -1901,10 +1901,19 @@ static DECLCALLBACK(void) tmR3TimerCallback(PRTTIMER pTimer, void *pvUser, uint6 - NOREF(pTimer); - - AssertCompile(TMCLOCK_MAX == 4); -+ -+ if (VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)) { - #ifdef DEBUG_Sander /* very annoying, keep it private. */ -- if (VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)) - Log(("tmR3TimerCallback: timer event still pending!!\n")); - #endif -+ /* -+ * The VMCPU_FF_TIMER flag could have been set by a non-destination -+ * EMT thread without waking the destination EMT thread. -+ */ -+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM); -+ return; -+ } -+ - if ( !VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER) - && ( pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].offSchedule /** @todo FIXME - reconsider offSchedule as a reason for running the timer queues. */ - || pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].offSchedule diff --git a/repos/ports/src/virtualbox/spec/nova/sup.cc b/repos/ports/src/virtualbox/spec/nova/sup.cc index d3ba666bac..712946ef32 100644 --- a/repos/ports/src/virtualbox/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox/spec/nova/sup.cc @@ -117,9 +117,24 @@ int SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned case VMMR0_DO_GVMM_SCHED_HALT: { + const uint64_t u64NowGip = RTTimeNanoTS(); + const uint64_t ns_diff = u64Arg > u64NowGip ? u64Arg - u64NowGip : 0; + + if (!ns_diff) + return VINF_SUCCESS; + + uint64_t const tsc_offset = genode_cpu_hz() * ns_diff / (1000*1000*1000); + uint64_t const tsc_abs = Genode::Trace::timestamp() + tsc_offset; + + using namespace Genode; + + if (ns_diff > RT_NS_1SEC) + warning(" more than 1 sec vcpu halt ", ns_diff, " ns"); + Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu); Assert(vcpu_handler); - vcpu_handler->halt(); + vcpu_handler->halt(tsc_abs); + return VINF_SUCCESS; } @@ -127,6 +142,11 @@ int SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned { Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu); Assert(vcpu_handler); + + /* don't wake the currently running thread again */ + if (vcpu_handler->utcb() == Genode::Thread::myself()->utcb()) + return VINF_SUCCESS; + vcpu_handler->wake_up(); return VINF_SUCCESS; } diff --git a/repos/ports/src/virtualbox/spec/nova/vcpu.h b/repos/ports/src/virtualbox/spec/nova/vcpu.h index 920dc02780..f168d82692 100644 --- a/repos/ports/src/virtualbox/spec/nova/vcpu.h +++ b/repos/ports/src/virtualbox/spec/nova/vcpu.h @@ -17,7 +17,6 @@ /* Genode includes */ #include -#include #include #include #include @@ -88,7 +87,6 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher, bool _irq_win; unsigned int _cpu_id; - Genode::Semaphore _halt_sem; unsigned int _last_inj_info; unsigned int _last_inj_error; @@ -758,14 +756,18 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher, } } - void halt() + void halt(Genode::uint64_t tsc_abs) { - _halt_sem.down(); + Assert(utcb() == Thread::myself()->utcb()); + + Genode::addr_t sem = native_thread().exc_pt_sel + Nova::SM_SEL_EC; + Nova::sm_ctrl(sem, Nova::SEMAPHORE_DOWNZERO, tsc_abs); } void wake_up() { - _halt_sem.up(); + Genode::addr_t sem = native_thread().exc_pt_sel + Nova::SM_SEL_EC; + Nova::sm_ctrl(sem, Nova::SEMAPHORE_UP); } int run_hw(PVMR0 pVMR0) diff --git a/repos/ports/src/virtualbox5/patches/series b/repos/ports/src/virtualbox5/patches/series index 97f4e23a9a..cab29de2b3 100644 --- a/repos/ports/src/virtualbox5/patches/series +++ b/repos/ports/src/virtualbox5/patches/series @@ -3,7 +3,6 @@ vbox_main.patch vga_vbva.patch vmmdev.patch usb.patch -tm_smp.patch vmm.patch iem_wip.patch dbg.patch diff --git a/repos/ports/src/virtualbox5/patches/tm_smp.patch b/repos/ports/src/virtualbox5/patches/tm_smp.patch deleted file mode 100644 index 085d180bc3..0000000000 --- a/repos/ports/src/virtualbox5/patches/tm_smp.patch +++ /dev/null @@ -1,35 +0,0 @@ -tm_smp.patch - -diff --git a/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp b/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp -index c3bc22d..33d705c 100644 ---- a/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp -+++ b/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp -@@ -210,7 +210,7 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM) - pVM->tm.s.paTimerQueuesRC = MMHyperR3ToRC(pVM, pv); - - pVM->tm.s.offVM = RT_OFFSETOF(VM, tm.s); -- pVM->tm.s.idTimerCpu = pVM->cCpus - 1; /* The last CPU. */ -+ pVM->tm.s.idTimerCpu = 0; /* The first CPU. */ - pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].enmClock = TMCLOCK_VIRTUAL; - pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].u64Expire = INT64_MAX; - pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].enmClock = TMCLOCK_VIRTUAL_SYNC; -@@ -1901,10 +1901,18 @@ static DECLCALLBACK(void) tmR3TimerCallback(PRTTIMER pTimer, void *pvUser, uint6 - AssertCompile(TMCLOCK_MAX == 4); - STAM_COUNTER_INC(&pVM->tm.s.StatTimerCallback); - -+ if (VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)) { - #ifdef DEBUG_Sander /* very annoying, keep it private. */ -- if (VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)) - Log(("tmR3TimerCallback: timer event still pending!!\n")); - #endif -+ /* -+ * The VMCPU_FF_TIMER flag could have been set by a non-destination -+ * EMT thread without waking the destination EMT thread. -+ */ -+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM); -+ return; -+ } -+ - if ( !VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER) - && ( pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].offSchedule /** @todo FIXME - reconsider offSchedule as a reason for running the timer queues. */ - || pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].offSchedule diff --git a/repos/ports/src/virtualbox5/spec/nova/sup.cc b/repos/ports/src/virtualbox5/spec/nova/sup.cc index 21e824836f..e44ffb4dd4 100644 --- a/repos/ports/src/virtualbox5/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox5/spec/nova/sup.cc @@ -148,15 +148,24 @@ int SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned case VMMR0_DO_GVMM_SCHED_HALT: { + const uint64_t u64NowGip = RTTimeNanoTS(); + const uint64_t ns_diff = u64Arg > u64NowGip ? u64Arg - u64NowGip : 0; + + if (!ns_diff) + return VINF_SUCCESS; + + uint64_t const tsc_offset = genode_cpu_hz() * ns_diff / (1000*1000*1000); + uint64_t const tsc_abs = Genode::Trace::timestamp() + tsc_offset; + + using namespace Genode; + + if (ns_diff > RT_NS_1SEC) + warning(" more than 1 sec vcpu halt ", ns_diff, " ns"); + Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu); Assert(vcpu_handler); -/* - char txt_name[32]; - Genode::Thread_base::myself()->name(txt_name, sizeof(txt_name)); - PINF("%s - halt - rip=%p", txt_name, __builtin_return_address(0)); -*/ - vcpu_handler->halt(); -// PINF("%s - woken up", txt_name); + vcpu_handler->halt(tsc_abs); + return VINF_SUCCESS; } @@ -164,11 +173,11 @@ int SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned { Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu); Assert(vcpu_handler); -/* - char txt_name[32]; - Genode::Thread_base::myself()->name(txt_name, sizeof(txt_name)); - PINF("%s - wakeup - rip=%p", txt_name, __builtin_return_address(0)); -*/ + + /* don't wake the currently running thread again */ + if (vcpu_handler->utcb() == Genode::Thread::myself()->utcb()) + return VINF_SUCCESS; + vcpu_handler->wake_up(); return VINF_SUCCESS; } diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu.h b/repos/ports/src/virtualbox5/spec/nova/vcpu.h index 6b64e02b9b..0c8b5e0abc 100644 --- a/repos/ports/src/virtualbox5/spec/nova/vcpu.h +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu.h @@ -17,7 +17,6 @@ /* Genode includes */ #include -#include #include #include #include @@ -42,6 +41,8 @@ #include +#include + /* Genode's VirtualBox includes */ #include "sup.h" @@ -86,7 +87,6 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher, bool _irq_win; unsigned int _cpu_id; - Genode::Semaphore _halt_sem; unsigned int _last_inj_info; unsigned int _last_inj_error; @@ -758,14 +758,18 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher, } } - void halt() + void halt(Genode::uint64_t tsc_abs) { - _halt_sem.down(); + Assert(utcb() == Thread::myself()->utcb()); + + Genode::addr_t sem = native_thread().exc_pt_sel + Nova::SM_SEL_EC; + Nova::sm_ctrl(sem, Nova::SEMAPHORE_DOWNZERO, tsc_abs); } void wake_up() { - _halt_sem.up(); + Genode::addr_t sem = native_thread().exc_pt_sel + Nova::SM_SEL_EC; + Nova::sm_ctrl(sem, Nova::SEMAPHORE_UP); } int run_hw(PVMR0 pVMR0)