diff options
| author | Yicong Yang <yang.yicong@picoheart.com> | 2026-07-28 22:19:38 +0800 |
|---|---|---|
| committer | Anup Patel <anup@brainfault.org> | 2026-07-29 22:30:06 +0530 |
| commit | e0ba6bf6579d14148fcc47eebc5daa552b80a5f1 (patch) | |
| tree | 95b880e3bce5c2efc411ad6f8a8c910d1dc6e731 | |
| parent | 739dfb8b4b768f553463125253c87ff2c86ac036 (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.c | 14 |
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; } |
