summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYicong Yang <yang.yicong@picoheart.com>2026-07-28 22:19:38 +0800
committerAnup Patel <anup@brainfault.org>2026-07-29 22:30:06 +0530
commite0ba6bf6579d14148fcc47eebc5daa552b80a5f1 (patch)
tree95b880e3bce5c2efc411ad6f8a8c910d1dc6e731
parent739dfb8b4b768f553463125253c87ff2c86ac036 (diff)
RISC-V: KVM: Use try_cmpxchg for IMSIC MRIF RMW
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@picoheart.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20260728141938.95845-1-yang.yicong@picoheart.com Signed-off-by: Anup Patel <anup@brainfault.org>
-rw-r--r--arch/riscv/kvm/aia_imsic.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
index d38f5de0834c..bea9ec7192cd 100644
--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -220,15 +220,11 @@ 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;
}