From 3250f1951beb14ee67df807aa709cccbc404da71 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Tue, 15 Nov 2022 15:37:37 +0100 Subject: [PATCH] vbox6: gim system time update measurement 200 TSC ticks for max measurement duration can get too small on platforms with high TSC frequencies (e.g., >3GHz) and low CPU frequencies often caused by HWP configurations. Therefore, we express the measurement duration in NS (not ticks) and calculate max duration ticks using the TSC frequency. This way the max duration becomes independent of the TSC frequency. fixes #4672 --- repos/ports/src/virtualbox6/sup_gim.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) 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++) {