xen/riscv: manage IRQ_DISABLED flag in APLIC irq enable/disable callbacks

desc->status is only set once during setup_irq(), but interrupts can be
enabled/disabled at runtime, so update it in the corresponding callbacks.

For the purposes of the FENCE instruction, CSR read accesses are
classified as device input (I) and CSR write accesses as device output
(O), while the barriers used by spin locks (fence rw,rw) only order
normal memory accesses. An explicit wmb() (fence ow,ow) is therefore
added in aplic_irq_{enable,disable}() to order the desc->status update
with respect to the IMSIC CSR write.

Fixes: d4676a1398 ("xen/riscv: implementation of aplic and imsic operations")
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Oleksii Kurochko authored and Jan Beulich committed 2026-07-28 10:08:02 +02:00
1 parent 59b18eb757
commit 78607876a2
1 file changed
+19
+19
View File
@@ -134,6 +134,15 @@ static void cf_check aplic_irq_enable(struct irq_desc *desc)
spin_lock(&aplic.lock);
desc->status &= ~IRQ_DISABLED;
/*
* wmb() (fence ow,ow) orders the ->status memory write (w) before the
* CSR write inside imsic_irq_enable() (device output, o on RISC-V).
* arch_lock_release_barrier() uses fence rw,rw which does not cover
* device output (o), so wmb() is required to close that gap.
*/
wmb();
/* Enable interrupt in IMSIC */
imsic_irq_enable(desc->irq);
@@ -161,6 +170,16 @@ static void cf_check aplic_irq_disable(struct irq_desc *desc)
/* Disable interrupt in IMSIC */
imsic_irq_disable(desc->irq);
/*
* wmb() (fence ow,ow) ensures the CSR write (device output, o) inside
* imsic_irq_disable() is globally visible before ->status is marked
* IRQ_DISABLED. imsic_irq_disable()'s spin_unlock uses fence rw,rw
* which does not order device output (o) writes before subsequent
* memory writes (w), so an explicit wmb() is needed here.
*/
wmb();
desc->status |= IRQ_DISABLED;
spin_unlock(&aplic.lock);
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.