[PATCH] RISC-V: KVM: Use try_cmpxchg for IMSIC MRIF RMW
Yicong Yang
yang.yicong at picoheart.com
Tue Jul 28 09:36:37 PDT 2026
On 7/28/26 11:57 PM, Anup Patel wrote:
> On Tue, Jul 28, 2026 at 7:49 PM Yicong Yang <yang.yicong at picoheart.com> wrote:
>>
>> 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));
>
> This patch is already broken because "old_val = READ_ONCE(*ptr);"
> must be done inside the do { ... } while (...)
>
try_cmpxhg() will update the &old_val if failed to exchange, then
a second READ_ONCE() within the loop will be redundant, right?
thanks.
More information about the linux-riscv
mailing list