[PATCH] KVM: riscv: aia: use lr.d/sc.d on RV64 in imsic_mrif_atomic_rmw

Jun Sun jsun at junsun.net
Tue Jun 9 11:37:24 PDT 2026


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 at junsun.net>
---
 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




More information about the linux-riscv mailing list