[PATCH] RISC-V: KVM: Use try_cmpxchg for IMSIC MRIF RMW

Yicong Yang yang.yicong at picoheart.com
Tue Jul 28 07:19:38 PDT 2026


Currently the RMW for IMSIC MRIF is implemented with
word LRSC loop. This will only cover the lower 32bit
on a 64bit system. Instead of guard the implementation
with CONFIG_64BIT here, use try_cmpxchg() wrapper
which has already take care this to fix this issue.
It can also use AMO instructions on supported system.

Fixes: db8b7e97d613 ("RISC-V: KVM: Add in-kernel virtualization of AIA IMSIC")
Signed-off-by: Yicong Yang <yang.yicong at picoheart.com>
---
 arch/riscv/kvm/aia_imsic.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
index d38f5de0834c..c922c037344c 100644
--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -220,15 +220,12 @@ static unsigned long imsic_mrif_atomic_rmw(struct imsic_mrif *mrif,
 {
 	unsigned long old_val = 0, tmp = 0;
 
-	__asm__ __volatile__ (
-		"0:	lr.w.aq   %1, %0\n"
-		"	and       %2, %1, %3\n"
-		"	or        %2, %2, %4\n"
-		"	sc.w.rl   %2, %2, %0\n"
-		"	bnez      %2, 0b"
-		: "+A" (*ptr), "+r" (old_val), "+r" (tmp)
-		: "r" (~wr_mask), "r" (new_val & wr_mask)
-		: "memory");
+	new_val &= wr_mask;
+
+	old_val = READ_ONCE(*ptr);
+	do {
+		tmp = (old_val & ~wr_mask) | new_val;
+	} while (!try_cmpxchg(ptr, &old_val, tmp));
 
 	return old_val;
 }
-- 
2.50.1 (Apple Git-155)



More information about the linux-riscv mailing list