]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: selftests: vgic_irq: Add Group-0 enable test
authorMarc Zyngier <maz@kernel.org>
Thu, 20 Nov 2025 17:25:38 +0000 (17:25 +0000)
committerOliver Upton <oupton@kernel.org>
Mon, 24 Nov 2025 22:29:15 +0000 (14:29 -0800)
Add a new test case that inject a Group-0 interrupt together
with a bunch of Group-1 interrupts, Ack/EOI the G1 interrupts,
and only then enable G0, expecting to get the G0 interrupt.

Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Tested-by: Mark Brown <broonie@kernel.org>
Link: https://msgid.link/20251120172540.2267180-49-maz@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>
tools/testing/selftests/kvm/arm64/vgic_irq.c

index a53ab809fe8ae14ed647b8a63e16aa9fe4ecbc21..ff2c75749f5c54c1e8af90b6fee615d5cf3a56fc 100644 (file)
@@ -846,6 +846,54 @@ static void guest_code_asym_dir(struct test_args *args, int cpuid)
        GUEST_DONE();
 }
 
+static void guest_code_group_en(struct test_args *args, int cpuid)
+{
+       uint32_t intid;
+
+       gic_init(GIC_V3, 2);
+
+       gic_set_eoi_split(0);
+       gic_set_priority_mask(CPU_PRIO_MASK);
+       /* SGI0 is G0, which is disabled */
+       gic_irq_set_group(0, 0);
+
+       /* Configure all SGIs with decreasing priority */
+       for (intid = 0; intid < MIN_PPI; intid++) {
+               gic_set_priority(intid, (intid + 1) * 8);
+               gic_irq_enable(intid);
+               gic_irq_set_pending(intid);
+       }
+
+       /* Ack and EOI all G1 interrupts */
+       for (int i = 1; i < MIN_PPI; i++) {
+               intid = wait_for_and_activate_irq();
+
+               GUEST_ASSERT(intid < MIN_PPI);
+               gic_set_eoi(intid);
+               isb();
+       }
+
+       /*
+        * Check that SGI0 is still pending, inactive, and that we cannot
+        * ack anything.
+        */
+       GUEST_ASSERT(gic_irq_get_pending(0));
+       GUEST_ASSERT(!gic_irq_get_active(0));
+       GUEST_ASSERT_IAR_EMPTY();
+       GUEST_ASSERT(read_sysreg_s(SYS_ICC_IAR0_EL1) == IAR_SPURIOUS);
+
+       /* Open the G0 gates, and verify we can ack SGI0 */
+       write_sysreg_s(1, SYS_ICC_IGRPEN0_EL1);
+       isb();
+
+       do {
+               intid = read_sysreg_s(SYS_ICC_IAR0_EL1);
+       } while (intid == IAR_SPURIOUS);
+
+       GUEST_ASSERT(intid == 0);
+       GUEST_DONE();
+}
+
 static void *test_vcpu_run(void *arg)
 {
        struct kvm_vcpu *vcpu = arg;
@@ -962,6 +1010,7 @@ int main(int argc, char **argv)
                test_vgic(nr_irqs, true /* level */, false /* eoi_split */);
                test_vgic(nr_irqs, true /* level */, true /* eoi_split */);
                test_vgic_two_cpus(guest_code_asym_dir);
+               test_vgic_two_cpus(guest_code_group_en);
        } else {
                test_vgic(nr_irqs, level_sensitive, eoi_split);
        }