[PATCH] KVM: riscv: aia: use lr.d/sc.d on RV64 in imsic_mrif_atomic_rmw
From: Jun Sun
Date: Tue Jun 09 2026 - 14:37:37 EST
imsic_mrif_atomic_rmw() uses lr.w.aq/sc.w.rl (32-bit) on an
`unsigned long *ptr`. On RV64 this drops the upper 32 bits of every
guest EIE/EIP write, so MSIs to EIIDs >= 32 are silently lost in AIA
EMUL mode. Gate on CONFIG_32BIT and use lr.d.aq/sc.d.rl on RV64.
Signed-off-by: Jun Sun <jsun@xxxxxxxxxx>
---
arch/riscv/kvm/aia_imsic.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
index 11422cb95a64..933292683a05 100644
--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -221,10 +221,17 @@ static unsigned long imsic_mrif_atomic_rmw(struct imsic_mrif *mrif,
unsigned long old_val = 0, tmp = 0;
__asm__ __volatile__ (
+#ifdef CONFIG_32BIT
"0: lr.w.aq %1, %0\n"
" and %2, %1, %3\n"
" or %2, %2, %4\n"
" sc.w.rl %2, %2, %0\n"
+#else
+ "0: lr.d.aq %1, %0\n"
+ " and %2, %1, %3\n"
+ " or %2, %2, %4\n"
+ " sc.d.rl %2, %2, %0\n"
+#endif
" bnez %2, 0b"
: "+A" (*ptr), "+r" (old_val), "+r" (tmp)
: "r" (~wr_mask), "r" (new_val & wr_mask)
--
2.34.1