With time counter test, it is to verify that time count starts from 0
and always grows up then.

Signed-off-by: Bibo Mao <[email protected]>
---
 .../selftests/kvm/lib/loongarch/processor.c   |  9 ++++++
 .../selftests/kvm/loongarch/arch_timer.c      | 29 +++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c 
b/tools/testing/selftests/kvm/lib/loongarch/processor.c
index 436990258068..ac2ffd076bff 100644
--- a/tools/testing/selftests/kvm/lib/loongarch/processor.c
+++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c
@@ -3,6 +3,7 @@
 #include <assert.h>
 #include <linux/compiler.h>
 
+#include <asm/kvm.h>
 #include "kvm_util.h"
 #include "processor.h"
 #include "ucall_common.h"
@@ -256,6 +257,11 @@ static void loongarch_set_csr(struct kvm_vcpu *vcpu, 
uint64_t id, uint64_t val)
        __vcpu_set_reg(vcpu, csrid, val);
 }
 
+static void loongarch_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val)
+{
+       __vcpu_set_reg(vcpu, id, val);
+}
+
 static void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
        int width;
@@ -279,6 +285,9 @@ static void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
        loongarch_set_csr(vcpu, LOONGARCH_CSR_ECFG, 0);
        loongarch_set_csr(vcpu, LOONGARCH_CSR_TCFG, 0);
        loongarch_set_csr(vcpu, LOONGARCH_CSR_ASID, 1);
+       /* time count start from 0 */
+       val = 0;
+       loongarch_set_reg(vcpu, KVM_REG_LOONGARCH_COUNTER, val);
 
        val = 0;
        width = vm->page_shift - 3;
diff --git a/tools/testing/selftests/kvm/loongarch/arch_timer.c 
b/tools/testing/selftests/kvm/loongarch/arch_timer.c
index 579132a082cd..f3a25a0163fc 100644
--- a/tools/testing/selftests/kvm/loongarch/arch_timer.c
+++ b/tools/testing/selftests/kvm/loongarch/arch_timer.c
@@ -133,10 +133,39 @@ static void guest_test_emulate_timer(uint32_t cpu)
        local_irq_enable();
 }
 
+static void guest_time_count_test(uint32_t cpu)
+{
+       uint32_t config_iter;
+       unsigned long start, end, prev, us;
+
+       /* Assuming that test case starts to run in 1 second */
+       start = timer_get_cycles();
+       us = msec_to_cycles(1000);
+       __GUEST_ASSERT(start <= us,
+                       "start = 0x%lx, us = 0x%lx.\n",
+                       start, us);
+
+       us = msec_to_cycles(test_args.timer_period_ms);
+       for (config_iter = 0; config_iter < test_args.nr_iter; config_iter++) {
+               start = timer_get_cycles();
+               end = start + us;
+               /* test time count growing up always */
+               while (start < end) {
+                       prev = start;
+                       start = timer_get_cycles();
+                       __GUEST_ASSERT(prev <= start,
+                                       "prev = 0x%lx, start = 0x%lx.\n",
+                                       prev, start);
+               }
+       }
+}
+
 static void guest_code(void)
 {
        uint32_t cpu = guest_get_vcpuid();
 
+       /* must run at first */
+       guest_time_count_test(cpu);
        timer_irq_enable();
        local_irq_enable();
        guest_test_oneshot_timer(cpu);
-- 
2.39.3


Reply via email to