Commit 1c9c71ac authored by Marc Zyngier's avatar Marc Zyngier Committed by Oliver Upton
Browse files

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: default avatarFuad Tabba <tabba@google.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Tested-by: default avatarMark Brown <broonie@kernel.org>
Link: https://msgid.link/20251120172540.2267180-49-maz@kernel.org


Signed-off-by: default avatarOliver Upton <oupton@kernel.org>
parent d2dee2e8
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -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);
	}