OSDN Git Service

irqchip/sifive-plic: Separate the enable and mask operations
authorSamuel Holland <samuel@sholland.org>
Fri, 1 Jul 2022 20:24:40 +0000 (15:24 -0500)
committerMarc Zyngier <maz@kernel.org>
Sun, 10 Jul 2022 08:50:04 +0000 (09:50 +0100)
commita1706a1c5062e0908528170f853601ed53f428c8
treefdf7905b29541716a8f3766f887df8e99fd4c9bc
parentde078949218242d57f791b63fac87cdb09cb0424
irqchip/sifive-plic: Separate the enable and mask operations

The PLIC has two per-IRQ checks before sending an IRQ to a hart context.
First, it checks that the IRQ's priority is nonzero. Then, it checks
that the enable bit is set for that combination of IRQ and context.

Currently, the PLIC driver sets both the priority value and the enable
bit in its (un)mask operations. However, modifying the enable bit is
problematic for two reasons:
  1) The enable bits are packed, so changes are not atomic and require
     taking a spinlock.
  2) The following requirement from the PLIC spec, which explains the
     racy (un)mask operations in plic_irq_eoi():

       If the completion ID does not match an interrupt source
       that is currently enabled for the target, the completion
       is silently ignored.

Both of these problems are solved by using the priority value to mask
IRQs. Each IRQ has a separate priority register, so writing the priority
value is atomic. And since the enable bit remains set while an IRQ is
masked, the EOI operation works normally. The enable bits are still used
to control the IRQ's affinity.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20220701202440.59059-3-samuel@sholland.org
drivers/irqchip/irq-sifive-plic.c