Provide a generic function to read the system counter from the guest for timing purposes. A common and important way to measure guest performance is to measure the amount of time different actions take in the guest. Provide also a mathematical conversion from cycles to nanoseconds and a macro for timing individual statements. Substitute the previous custom implementation of a similar function in system_counter_offset_test with this new implementation. Signed-off-by: Colton Lewis <coltonlewis@xxxxxxxxxx> --- .../testing/selftests/kvm/include/kvm_util.h | 15 ++++++++++ tools/testing/selftests/kvm/lib/kvm_util.c | 30 +++++++++++++++++++ .../kvm/system_counter_offset_test.c | 10 ++----- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index c9286811a4cb..8b478eabee4c 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -10,4 +10,19 @@ #include "kvm_util_base.h" #include "ucall_common.h" +#if defined(__aarch64__) || defined(__x86_64__) + +uint64_t cycles_read(void); +double cycles_to_ns(struct kvm_vcpu *vcpu, double cycles); + +#define MEASURE_CYCLES(x) \ + ({ \ + uint64_t start; \ + start = cycles_read(); \ + x; \ + cycles_read() - start; \ + }) + +#endif + #endif /* SELFTEST_KVM_UTIL_H */ diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 3ea24a5f4c43..780481a92efe 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2135,3 +2135,34 @@ void __attribute((constructor)) kvm_selftest_init(void) kvm_selftest_arch_init(); } + +#if defined(__aarch64__) + +#include "arch_timer.h" + +uint64_t cycles_read(void) +{ + return timer_get_cntct(VIRTUAL); +} + +double cycles_to_ns(struct kvm_vcpu *vcpu, double cycles) +{ + return cycles * (1e9 / timer_get_cntfrq()); +} + +#elif defined(__x86_64__) + +#include "processor.h" + +uint64_t cycles_read(void) +{ + return rdtsc(); +} + +double cycles_to_ns(struct kvm_vcpu *vcpu, double cycles) +{ + uint64_t tsc_khz = __vcpu_ioctl(vcpu, KVM_GET_TSC_KHZ, NULL); + + return cycles * (1e9 / (tsc_khz * 1000)); +} +#endif diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c index 7f5b330b6a1b..44101d0fcb48 100644 --- a/tools/testing/selftests/kvm/system_counter_offset_test.c +++ b/tools/testing/selftests/kvm/system_counter_offset_test.c @@ -39,14 +39,9 @@ static void setup_system_counter(struct kvm_vcpu *vcpu, struct test_case *test) &test->tsc_offset); } -static uint64_t guest_read_system_counter(struct test_case *test) -{ - return rdtsc(); -} - static uint64_t host_read_guest_system_counter(struct test_case *test) { - return rdtsc() + test->tsc_offset; + return cycles_read() + test->tsc_offset; } #else /* __x86_64__ */ @@ -63,9 +58,8 @@ static void guest_main(void) int i; for (i = 0; i < ARRAY_SIZE(test_cases); i++) { - struct test_case *test = &test_cases[i]; - GUEST_SYNC_CLOCK(i, guest_read_system_counter(test)); + GUEST_SYNC_CLOCK(i, cycles_read()); } } -- 2.40.0.rc1.284.g88254d51c5-goog