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
This commit is contained in:
Sebastian Sumpf 2022-11-15 15:37:37 +01:00 committed by Christian Helmuth
parent b78b543011
commit 3250f1951b

View File

@ -27,6 +27,7 @@
/* Genode includes */
#include <base/log.h>
#include <util/misc_math.h>
/* VirtualBox includes */
#include <GIMInternal.h> /* 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++) {