Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: LoongArch: selftests: Add SW emulated timer test case

This test case setup one-shot timer and execute idle instruction
immediately to indicate giving up CPU, hypervisor will emulate SW
hrtimer and wakeup vCPU when SW hrtimer is fired.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>

authored by

Bibo Mao and committed by
Huacai Chen
4e882409 df417423

+40
+40
tools/testing/selftests/kvm/loongarch/arch_timer.c
··· 9 9 #include "timer_test.h" 10 10 #include "ucall_common.h" 11 11 12 + static void do_idle(void) 13 + { 14 + unsigned int intid; 15 + unsigned long estat; 16 + 17 + __asm__ __volatile__("idle 0" : : : "memory"); 18 + 19 + estat = csr_read(LOONGARCH_CSR_ESTAT); 20 + intid = !!(estat & BIT(INT_TI)); 21 + 22 + /* Make sure pending timer IRQ arrived */ 23 + GUEST_ASSERT_EQ(intid, 1); 24 + csr_write(CSR_TINTCLR_TI, LOONGARCH_CSR_TINTCLR); 25 + } 26 + 12 27 static void guest_irq_handler(struct ex_regs *regs) 13 28 { 14 29 unsigned int intid; ··· 112 97 } 113 98 } 114 99 100 + static void guest_test_emulate_timer(uint32_t cpu) 101 + { 102 + uint32_t config_iter; 103 + uint64_t xcnt_diff_us, us; 104 + struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu]; 105 + 106 + local_irq_disable(); 107 + shared_data->nr_iter = 0; 108 + us = msecs_to_usecs(test_args.timer_period_ms); 109 + for (config_iter = 0; config_iter < test_args.nr_iter; config_iter++) { 110 + shared_data->xcnt = timer_get_cycles(); 111 + 112 + /* Setup the next interrupt */ 113 + timer_set_next_cmp_ms(test_args.timer_period_ms, false); 114 + do_idle(); 115 + 116 + xcnt_diff_us = cycles_to_usec(timer_get_cycles() - shared_data->xcnt); 117 + __GUEST_ASSERT(xcnt_diff_us >= us, 118 + "xcnt_diff_us = 0x%lx, us = 0x%lx.\n", 119 + xcnt_diff_us, us); 120 + } 121 + local_irq_enable(); 122 + } 123 + 115 124 static void guest_code(void) 116 125 { 117 126 uint32_t cpu = guest_get_vcpuid(); ··· 144 105 local_irq_enable(); 145 106 guest_test_period_timer(cpu); 146 107 guest_test_oneshot_timer(cpu); 108 + guest_test_emulate_timer(cpu); 147 109 148 110 GUEST_DONE(); 149 111 }