[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251104113700.1561752-6-maobibo@loongson.cn>
Date: Tue, 4 Nov 2025 19:36:57 +0800
From: Bibo Mao <maobibo@...ngson.cn>
To: Paolo Bonzini <pbonzini@...hat.com>,
Sean Christopherson <seanjc@...gle.com>,
Huacai Chen <chenhuacai@...nel.org>,
Tianrui Zhao <zhaotianrui@...ngson.cn>,
Shuah Khan <shuah@...nel.org>
Cc: linux-kernel@...r.kernel.org,
kvm@...r.kernel.org,
loongarch@...ts.linux.dev,
linux-kselftest@...r.kernel.org
Subject: [PATCH v2 5/7] KVM: LoongArch: selftests: Add period mode timer test
Period mode timer is added. Timer only need program once with period
mode, its compared tick value will reload when timer is fired.
Signed-off-by: Bibo Mao <maobibo@...ngson.cn>
---
.../kvm/include/loongarch/arch_timer.h | 5 ++++
.../selftests/kvm/loongarch/arch_timer.c | 28 +++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/tools/testing/selftests/kvm/include/loongarch/arch_timer.h b/tools/testing/selftests/kvm/include/loongarch/arch_timer.h
index 94b1cba2744d..b6399e748f72 100644
--- a/tools/testing/selftests/kvm/include/loongarch/arch_timer.h
+++ b/tools/testing/selftests/kvm/include/loongarch/arch_timer.h
@@ -36,6 +36,11 @@ static inline void timer_set_next_cmp_ms(unsigned int msec, bool period)
csr_write(val, LOONGARCH_CSR_TCFG);
}
+static inline void disable_timer(void)
+{
+ csr_write(0, LOONGARCH_CSR_TCFG);
+}
+
static inline unsigned long timer_get_val(void)
{
return csr_read(LOONGARCH_CSR_TVAL);
diff --git a/tools/testing/selftests/kvm/loongarch/arch_timer.c b/tools/testing/selftests/kvm/loongarch/arch_timer.c
index 2a2cebcf3885..a4a39f24bb7e 100644
--- a/tools/testing/selftests/kvm/loongarch/arch_timer.c
+++ b/tools/testing/selftests/kvm/loongarch/arch_timer.c
@@ -23,6 +23,13 @@ static void guest_irq_handler(struct ex_regs *regs)
GUEST_ASSERT_EQ(intid, 1);
cfg = timer_get_cfg();
+ if (cfg & CSR_TCFG_PERIOD) {
+ WRITE_ONCE(shared_data->nr_iter, shared_data->nr_iter - 1);
+ if (shared_data->nr_iter == 0)
+ disable_timer();
+ csr_write(CSR_TINTCLR_TI, LOONGARCH_CSR_TINTCLR);
+ return;
+ }
/*
* On physical machine, value of LOONGARCH_CSR_TVAL is BIT_ULL(48) - 1
@@ -67,6 +74,26 @@ static void guest_test_oneshot_timer(uint32_t cpu)
}
}
+static void guest_test_period_timer(uint32_t cpu)
+{
+ uint32_t irq_iter;
+ uint64_t us;
+ struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
+
+ shared_data->nr_iter = test_args.nr_iter;
+ shared_data->xcnt = timer_get_cycles();
+ us = msecs_to_usecs(test_args.timer_period_ms) + test_args.timer_err_margin_us;
+ timer_set_next_cmp_ms(test_args.timer_period_ms, true);
+ /* Setup a timeout for the interrupt to arrive */
+ udelay(us * test_args.nr_iter);
+ irq_iter = READ_ONCE(shared_data->nr_iter);
+ __GUEST_ASSERT(irq_iter == 0,
+ "irq_iter = 0x%x.\n"
+ " Guest period timer interrupt was not triggered within the specified\n"
+ " interval, try to increase the error margin by [-e] option.\n",
+ irq_iter);
+}
+
static void guest_code(void)
{
uint32_t cpu = guest_get_vcpuid();
@@ -74,6 +101,7 @@ static void guest_code(void)
timer_irq_enable();
local_irq_enable();
guest_test_oneshot_timer(cpu);
+ guest_test_period_timer(cpu);
GUEST_DONE();
}
--
2.39.3
Powered by blists - more mailing lists