KVM: arm64: selftests: vgic_irq: Add Group-0 enable test

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>
This commit is contained in:
Marc Zyngier 2025-11-20 17:25:38 +00:00 committed by Oliver Upton
parent d2dee2e849
commit 1c9c71ac1b

View 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);
}