diff --git a/repos/ports/src/virtualbox6/sup_gim.cc b/repos/ports/src/virtualbox6/sup_gim.cc
index f19576bca8..e9c21d9394 100644
--- a/repos/ports/src/virtualbox6/sup_gim.cc
+++ b/repos/ports/src/virtualbox6/sup_gim.cc
@@ -27,6 +27,7 @@
/* Genode includes */
#include
+#include
/* VirtualBox includes */
#include /* needed for access to VM::gim.s */
@@ -59,6 +60,18 @@ void Sup::update_gim_system_time(VM &vm, VMCPU &vmcpu)
uint64_t uTsc = 0;
uint64_t uVirtNanoTS = 0;
+ enum { MAX_MEASUREMENT_DURATION_NS = 400U };
+
+ /* calculate max duration from tsc */
+ PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
+ uint64_t max_ticks = MAX_MEASUREMENT_DURATION_NS;
+
+ if(pGip && pGip->u64CpuHz) {
+ /* round */
+ uint64_t ticks_per_ns = (pGip->u64CpuHz + 500'000'000) / 1'000'000'000;
+ max_ticks = max(ticks_per_ns * MAX_MEASUREMENT_DURATION_NS, max_ticks);
+ }
+
/*
* If we got preempted during the measurement, repeat.
*/
@@ -68,14 +81,14 @@ void Sup::update_gim_system_time(VM &vm, VMCPU &vmcpu)
uVirtNanoTS = TMVirtualGetNoCheck(&vm) | UINT64_C(1);
uint64_t const uTsc_again = TMCpuTickGetNoCheck(&vmcpu) | UINT64_C(1);
- enum { MAX_MEASUREMENT_DURATION = 200U };
- if (uTsc_again - uTsc < MAX_MEASUREMENT_DURATION)
+ if (uTsc_again - uTsc < max_ticks)
break;
if (round > 3 && round % 2 == 0)
warning("preemption during measurement, uTsc=", uTsc,
- " uTsc_again=", uTsc_again, " uVirtNanoTS=", uVirtNanoTS);
+ " uTsc_again=", uTsc_again, " uVirtNanoTS=", uVirtNanoTS,
+ " max_ticks=", max_ticks);
}
for (VMCPUID idCpu = 0; idCpu < vm.cCpus; idCpu++) {