]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: selftests: Use hyp timer IRQs when test runs at EL2
authorOliver Upton <oliver.upton@linux.dev>
Wed, 17 Sep 2025 21:20:39 +0000 (14:20 -0700)
committerMarc Zyngier <maz@kernel.org>
Wed, 24 Sep 2025 18:23:32 +0000 (19:23 +0100)
Arch timer registers are redirected to their hypervisor counterparts
when running in VHE EL2. This is great, except for the fact that the
hypervisor timers use different PPIs. Use the correct INTIDs when that
is the case.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
tools/testing/selftests/kvm/arm64/arch_timer.c
tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c
tools/testing/selftests/kvm/include/arm64/arch_timer.h

index c753013319bc67eb00d76c9cfcd3f4dd03e549b7..d592a4515399fcd8e4b39aa7e994c8dd1ccc4aad 100644 (file)
@@ -165,10 +165,8 @@ static void guest_code(void)
 static void test_init_timer_irq(struct kvm_vm *vm)
 {
        /* Timer initid should be same for all the vCPUs, so query only vCPU-0 */
-       vcpu_device_attr_get(vcpus[0], KVM_ARM_VCPU_TIMER_CTRL,
-                            KVM_ARM_VCPU_TIMER_IRQ_PTIMER, &ptimer_irq);
-       vcpu_device_attr_get(vcpus[0], KVM_ARM_VCPU_TIMER_CTRL,
-                            KVM_ARM_VCPU_TIMER_IRQ_VTIMER, &vtimer_irq);
+       ptimer_irq = vcpu_get_ptimer_irq(vcpus[0]);
+       vtimer_irq = vcpu_get_vtimer_irq(vcpus[0]);
 
        sync_global_to_guest(vm, ptimer_irq);
        sync_global_to_guest(vm, vtimer_irq);
index 5c60262f4c2e8780a17aefb1a78796829450ab06..91906414a474949c495eeb8b759b200bb5cd32b2 100644 (file)
@@ -924,10 +924,8 @@ static void test_run(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
 
 static void test_init_timer_irq(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
 {
-       vcpu_device_attr_get(vcpu, KVM_ARM_VCPU_TIMER_CTRL,
-                            KVM_ARM_VCPU_TIMER_IRQ_PTIMER, &ptimer_irq);
-       vcpu_device_attr_get(vcpu, KVM_ARM_VCPU_TIMER_CTRL,
-                            KVM_ARM_VCPU_TIMER_IRQ_VTIMER, &vtimer_irq);
+       ptimer_irq = vcpu_get_ptimer_irq(vcpu);
+       vtimer_irq = vcpu_get_vtimer_irq(vcpu);
 
        sync_global_to_guest(vm, ptimer_irq);
        sync_global_to_guest(vm, vtimer_irq);
index bf461de34785a32d74a07a4da1b26466d7c80348..e2c4e9f0010f467b7cd83603d4030d6db297276c 100644 (file)
@@ -155,4 +155,28 @@ static inline void timer_set_next_tval_ms(enum arch_timer timer, uint32_t msec)
        timer_set_tval(timer, msec_to_cycles(msec));
 }
 
+static inline u32 vcpu_get_vtimer_irq(struct kvm_vcpu *vcpu)
+{
+       u32 intid;
+       u64 attr;
+
+       attr = vcpu_has_el2(vcpu) ? KVM_ARM_VCPU_TIMER_IRQ_HVTIMER :
+                                   KVM_ARM_VCPU_TIMER_IRQ_VTIMER;
+       vcpu_device_attr_get(vcpu, KVM_ARM_VCPU_TIMER_CTRL, attr, &intid);
+
+       return intid;
+}
+
+static inline u32 vcpu_get_ptimer_irq(struct kvm_vcpu *vcpu)
+{
+       u32 intid;
+       u64 attr;
+
+       attr = vcpu_has_el2(vcpu) ? KVM_ARM_VCPU_TIMER_IRQ_HPTIMER :
+                                   KVM_ARM_VCPU_TIMER_IRQ_PTIMER;
+       vcpu_device_attr_get(vcpu, KVM_ARM_VCPU_TIMER_CTRL, attr, &intid);
+
+       return intid;
+}
+
 #endif /* SELFTEST_KVM_ARCH_TIMER_H */