From d3adadf4cfedca2a165cf0aefbe05f377cd9bad1 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Mon, 17 Jan 2022 09:23:25 +0100 Subject: [PATCH] virtualbox6: adapt watchdog timer interval dynamically Issue #4381 --- repos/ports/ports/virtualbox6.hash | 2 +- repos/ports/src/virtualbox6/nem.cc | 26 +++++++++ .../src/virtualbox6/patches/rttimer.patch | 54 +++++++++++++++++++ repos/ports/src/virtualbox6/patches/series | 1 + 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 repos/ports/src/virtualbox6/patches/rttimer.patch diff --git a/repos/ports/ports/virtualbox6.hash b/repos/ports/ports/virtualbox6.hash index e01ed08739..d4c61036b9 100644 --- a/repos/ports/ports/virtualbox6.hash +++ b/repos/ports/ports/virtualbox6.hash @@ -1 +1 @@ -4520096005074d88433410752e88df1e748a80dd +7991a9853bb0a96cad9a54ebaf3290dfda9ae2d2 diff --git a/repos/ports/src/virtualbox6/nem.cc b/repos/ports/src/virtualbox6/nem.cc index 466f17d08d..d9a1b3de0a 100644 --- a/repos/ports/src/virtualbox6/nem.cc +++ b/repos/ports/src/virtualbox6/nem.cc @@ -14,9 +14,11 @@ /* VirtualBox includes */ #include /* must be included before CPUMInternal.h */ +#include /* must be included before TMInternal.h */ #define VMCPU_INCL_CPUM_GST_CTX /* needed for cpum.GstCtx */ #include /* enable access to cpum.s.* */ #include /* enable access to hm.s.* */ +#include /* enable access to tm.s.* */ #define RT_OS_WINDOWS /* needed for definition all nem.s members */ #include /* enable access to nem.s.* */ #undef RT_OS_WINDOWS @@ -253,6 +255,30 @@ VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu) { using namespace Sup; + /* + * Program the watchdog timer near the next expiring virtual sync timeout. + * Without this code the watchdog timer would be programmed to a fixed + * interval (10ms by default), which could be too high or cause too much + * CPU load if set lower. Other hosts use the VMX preemption timer, which + * is currently not available on Genode. + */ + { + static ::uint64_t current_interval_ns { 0 }; + static Mutex interval_mutex { }; + + Mutex::Guard guard(interval_mutex); + + ::uint64_t new_interval_ns = TMVirtualSyncGetNsToDeadline(pVM); + new_interval_ns = (new_interval_ns / RT_NS_1MS) * RT_NS_1MS; + new_interval_ns = max(new_interval_ns, 1 * RT_NS_1MS); + new_interval_ns = min(new_interval_ns, 10 * RT_NS_1MS); + + if (new_interval_ns != current_interval_ns) { + RTTimerChangeInterval(pVM->tm.s.pTimer, new_interval_ns); + current_interval_ns = new_interval_ns; + } + } + Vm &vm = *static_cast(pVM); /* commit on VM entry */ diff --git a/repos/ports/src/virtualbox6/patches/rttimer.patch b/repos/ports/src/virtualbox6/patches/rttimer.patch new file mode 100644 index 0000000000..d05308f749 --- /dev/null +++ b/repos/ports/src/virtualbox6/patches/rttimer.patch @@ -0,0 +1,54 @@ +Implement RTTimerChangeInterval() + +diff --git a/src/virtualbox6/src/VBox/Runtime/generic/timer-generic.cpp b/src/virtualbox6/src/VBox/Runtime/generic/timer-generic.cpp +index 6857bfb..7a32560 100644 +--- a/src/virtualbox6/src/VBox/Runtime/generic/timer-generic.cpp ++++ b/src/virtualbox6/src/VBox/Runtime/generic/timer-generic.cpp +@@ -223,10 +223,45 @@ RT_EXPORT_SYMBOL(RTTimerStop); + + RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) + { ++ /* implementation ported from timerlr-generic.cpp for Genode */ ++ + if (!rtTimerIsValid(pTimer)) + return VERR_INVALID_HANDLE; +- NOREF(u64NanoInterval); +- return VERR_NOT_SUPPORTED; ++ ++ PRTTIMER pThis = pTimer; ++ ++ /* ++ * Do the job accoring to state and caller. ++ */ ++ int rc; ++ if (pThis->fSuspended) ++ { ++ /* Stopped: Just update the interval. */ ++ ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval); ++ rc = VINF_SUCCESS; ++ } ++ else if (RTThreadSelf() == pThis->Thread) ++ { ++ /* Running: Updating interval from the callback. */ ++ uint64_t u64Now = RTTimeNanoTS(); ++ pThis->iTick = 0; ++ pThis->u64StartTS = u64Now; ++ pThis->u64NextTS = u64Now; ++ ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval); ++ rc = VINF_SUCCESS; ++ } ++ else ++ { ++ /* Running: Stopping */ ++ rc = RTTimerStop(pThis); ++ if (RT_SUCCESS(rc)) ++ { ++ ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval); ++ rc = RTTimerStart(pThis, 0); ++ } ++ } ++ ++ return rc; + } + RT_EXPORT_SYMBOL(RTTimerChangeInterval); + diff --git a/repos/ports/src/virtualbox6/patches/series b/repos/ports/src/virtualbox6/patches/series index c813ae53c0..a4c29a49c2 100644 --- a/repos/ports/src/virtualbox6/patches/series +++ b/repos/ports/src/virtualbox6/patches/series @@ -7,3 +7,4 @@ devahci.patch smp_sipi.patch tm_poke.patch exec_state.patch +rttimer.patch