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)