Commit 8e936e98 authored by Anup Patel's avatar Anup Patel Committed by Anup Patel
Browse files

RISC-V: KVM: Fix APLIC in_clrip[x] read emulation



The reads to APLIC in_clrip[x] registers returns rectified input values
of the interrupt sources.

A rectified input value of an interrupt source is defined by the section
"4.5.2 Source configurations (sourcecfg[1]–sourcecfg[1023])" of the
RISC-V AIA specification as:

    rectified input value = (incoming wire value) XOR (source is inverted)

Update the riscv_aplic_input() implementation to match the above.

Cc: stable@vger.kernel.org
Fixes: 74967aa2 ("RISC-V: KVM: Add in-kernel emulation of AIA APLIC")
Signed-off-by: default avatarAnup Patel <apatel@ventanamicro.com>
Signed-off-by: default avatarAnup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20240321085041.1955293-3-apatel@ventanamicro.com
parent d8dd9f11
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -197,16 +197,31 @@ static void aplic_write_enabled(struct aplic *aplic, u32 irq, bool enabled)

static bool aplic_read_input(struct aplic *aplic, u32 irq)
{
	bool ret;
	unsigned long flags;
	u32 sourcecfg, sm, raw_input, irq_inverted;
	struct aplic_irq *irqd;
	unsigned long flags;
	bool ret = false;

	if (!irq || aplic->nr_irqs <= irq)
		return false;
	irqd = &aplic->irqs[irq];

	raw_spin_lock_irqsave(&irqd->lock, flags);
	ret = (irqd->state & APLIC_IRQ_STATE_INPUT) ? true : false;

	sourcecfg = irqd->sourcecfg;
	if (sourcecfg & APLIC_SOURCECFG_D)
		goto skip;

	sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
	if (sm == APLIC_SOURCECFG_SM_INACTIVE)
		goto skip;

	raw_input = (irqd->state & APLIC_IRQ_STATE_INPUT) ? 1 : 0;
	irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW ||
			sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0;
	ret = !!(raw_input ^ irq_inverted);

skip:
	raw_spin_unlock_irqrestore(&irqd->lock, flags);

	return ret;