]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
riscv: Implement smp_cond_load8/16() with Zawrs
authorGuo Ren <guoren@linux.alibaba.com>
Tue, 17 Dec 2024 01:39:10 +0000 (20:39 -0500)
committerAlexandre Ghiti <alexghiti@rivosinc.com>
Tue, 18 Mar 2025 09:12:45 +0000 (09:12 +0000)
RISC-V code uses the queued spinlock implementation, which calls
the macros smp_cond_load_acquire for one byte. So, complement the
implementation of byte and halfword versions.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Link: https://lore.kernel.org/r/20241217013910.1039923-1-guoren@kernel.org
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
arch/riscv/include/asm/cmpxchg.h

index 427c41dde64319c01e520d746cdc42005264f655..2ec119eb147bb64039e78b3a83828f80be7980fe 100644 (file)
@@ -365,16 +365,48 @@ static __always_inline void __cmpwait(volatile void *ptr,
 {
        unsigned long tmp;
 
+       u32 *__ptr32b;
+       ulong __s, __val, __mask;
+
        asm goto(ALTERNATIVE("j %l[no_zawrs]", "nop",
                             0, RISCV_ISA_EXT_ZAWRS, 1)
                 : : : : no_zawrs);
 
        switch (size) {
        case 1:
-               fallthrough;
+               __ptr32b = (u32 *)((ulong)(ptr) & ~0x3);
+               __s = ((ulong)(ptr) & 0x3) * BITS_PER_BYTE;
+               __val = val << __s;
+               __mask = 0xff << __s;
+
+               asm volatile(
+               "       lr.w    %0, %1\n"
+               "       and     %0, %0, %3\n"
+               "       xor     %0, %0, %2\n"
+               "       bnez    %0, 1f\n"
+                       ZAWRS_WRS_NTO "\n"
+               "1:"
+               : "=&r" (tmp), "+A" (*(__ptr32b))
+               : "r" (__val), "r" (__mask)
+               : "memory");
+               break;
        case 2:
-               /* RISC-V doesn't have lr instructions on byte and half-word. */
-               goto no_zawrs;
+               __ptr32b = (u32 *)((ulong)(ptr) & ~0x3);
+               __s = ((ulong)(ptr) & 0x2) * BITS_PER_BYTE;
+               __val = val << __s;
+               __mask = 0xffff << __s;
+
+               asm volatile(
+               "       lr.w    %0, %1\n"
+               "       and     %0, %0, %3\n"
+               "       xor     %0, %0, %2\n"
+               "       bnez    %0, 1f\n"
+                       ZAWRS_WRS_NTO "\n"
+               "1:"
+               : "=&r" (tmp), "+A" (*(__ptr32b))
+               : "r" (__val), "r" (__mask)
+               : "memory");
+               break;
        case 4:
                asm volatile(
                "       lr.w    %0, %1\n"