[PATCH v3 1/2] KVM: selftests: Provide generic way to read system counter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Provide a generic function cycles_read to read the system counter from
the guest for timing purposes and a helper cycles_to_ns to convert to
nanoseconds. cycles_to_ns may overflow if the cycles argument goes
above 10 billion, but that is far outside the intended use of these
functions and different timing instruments should be
used. clocks_calc_mult_shift could be used to solve this problem, but
importing clocksource code here was annoying.

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>
---
 .../selftests/kvm/include/aarch64/processor.h       |  3 +++
 .../selftests/kvm/include/x86_64/processor.h        |  3 +++
 tools/testing/selftests/kvm/lib/aarch64/processor.c | 12 ++++++++++++
 tools/testing/selftests/kvm/lib/x86_64/processor.c  | 13 +++++++++++++
 .../selftests/kvm/system_counter_offset_test.c      | 10 ++--------
 5 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index 5f977528e09c..f65e491763e0 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -216,4 +216,7 @@ void smccc_hvc(uint32_t function_id, uint64_t arg0, uint64_t arg1,

 uint32_t guest_get_vcpuid(void);

+uint64_t cycles_read(void);
+uint64_t cycles_to_ns(struct kvm_vcpu *vcpu, uint64_t cycles);
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h
index 53ffa43c90db..5d977f95d5f5 100644
--- a/tools/testing/selftests/kvm/include/x86_64/processor.h
+++ b/tools/testing/selftests/kvm/include/x86_64/processor.h
@@ -1134,4 +1134,7 @@ void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
 #define PFERR_GUEST_PAGE_MASK	BIT_ULL(PFERR_GUEST_PAGE_BIT)
 #define PFERR_IMPLICIT_ACCESS	BIT_ULL(PFERR_IMPLICIT_ACCESS_BIT)

+uint64_t cycles_read(void);
+uint64_t cycles_to_ns(struct kvm_vcpu *vcpu, uint64_t cycles);
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c
index 5972a23b2765..5475a7e98d41 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
@@ -8,6 +8,7 @@
 #include <linux/compiler.h>
 #include <assert.h>

+#include "arch_timer.h"
 #include "guest_modes.h"
 #include "kvm_util.h"
 #include "processor.h"
@@ -551,3 +552,14 @@ void vm_vaddr_populate_bitmap(struct kvm_vm *vm)
 	sparsebit_set_num(vm->vpages_valid, 0,
 			  (1ULL << vm->va_bits) >> vm->page_shift);
 }
+
+uint64_t cycles_read(void)
+{
+	return timer_get_cntct(VIRTUAL);
+}
+
+uint64_t cycles_to_ns(struct kvm_vcpu *vcpu, uint64_t cycles)
+{
+	TEST_ASSERT(cycles < 10000000000, "Conversion to ns may overflow");
+	return cycles * NSEC_PER_SEC / timer_get_cntfrq();
+}
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index ae1e573d94ce..adef76bebff3 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -1270,3 +1270,16 @@ void kvm_selftest_arch_init(void)
 	host_cpu_is_intel = this_cpu_is_intel();
 	host_cpu_is_amd = this_cpu_is_amd();
 }
+
+uint64_t cycles_read(void)
+{
+	return rdtsc();
+}
+
+uint64_t cycles_to_ns(struct kvm_vcpu *vcpu, uint64_t cycles)
+{
+	uint64_t tsc_khz = __vcpu_ioctl(vcpu, KVM_GET_TSC_KHZ, NULL);
+
+	TEST_ASSERT(cycles < 10000000000, "Conversion to ns may overflow");
+	return cycles * NSEC_PER_SEC / (tsc_khz * 1000);
+}
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.348.gf938b09366-goog



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux