* [PATCH] riscv/futex: Bound number of LL/SC retries in cmpxchg
@ 2026-05-05 8:58 Davidlohr Bueso
0 siblings, 0 replies; only message in thread
From: Davidlohr Bueso @ 2026-05-05 8:58 UTC (permalink / raw)
To: pjw, palmer
Cc: aou, alex, tglx, mingo, peterz, dvhart, andrealmeid, dave,
linux-riscv, linux-kernel
futex_atomic_cmpxchg_inatomic() does an unbounded LR/SC retry loop while
(minimally) holding the hb lock + pf disabled. This can lead to pathological
cases from unpriviledged userspace pi operations.
Bound the retry loop to (arbitrarily) 128 iterations and bail: drop locks,
rechedule and retry the operation, similar to the arm64 variant, as of
03110a5cb216 ("arm64: futex: Bound number of LDXR/STXR loops in FUTEX_WAKE_OP").
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
---
Compile tested only.
arch/riscv/include/asm/futex.h | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
index 90c86b115e00..865701807014 100644
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -13,6 +13,8 @@
#include <asm/asm.h>
#include <asm/asm-extable.h>
+#define FUTEX_MAX_LOOPS 128
+
/* We don't even really need the extable code, but for now keep it simple */
#ifndef CONFIG_MMU
#define __enable_user_access() do { } while (0)
@@ -77,6 +79,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
int ret = 0;
+ unsigned int loops = FUTEX_MAX_LOOPS;
u32 val;
uintptr_t tmp;
@@ -85,16 +88,20 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
__enable_user_access();
__asm__ __volatile__ (
- "1: lr.w %[v],%[u] \n"
+ "1: lr.w %[v],%[u] \n"
" bne %[v],%z[ov],3f \n"
"2: sc.w.aqrl %[t],%z[nv],%[u] \n"
- " bnez %[t],1b \n"
+ " beqz %[t],3f \n"
+ " addi %[lp],%[lp],-1 \n"
+ " bnez %[lp],1b \n"
+ " li %[r],%[eagain] \n"
"3: \n"
_ASM_EXTABLE_UACCESS_ERR(1b, 3b, %[r]) \
_ASM_EXTABLE_UACCESS_ERR(2b, 3b, %[r]) \
- : [r] "+r" (ret), [v] "=&r" (val), [u] "+m" (*uaddr), [t] "=&r" (tmp)
- : [ov] "Jr" ((long)(int)oldval), [nv] "Jr" (newval)
+ : [r] "+r" (ret), [v] "=&r" (val), [u] "+m" (*uaddr),
+ [t] "=&r" (tmp), [lp] "+r" (loops)
+ : [ov] "Jr" ((long)(int)oldval), [nv] "Jr" (newval),
+ [eagain] "i" (-EAGAIN)
: "memory");
__disable_user_access();
--
2.39.5
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-05-05 8:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-05 8:58 [PATCH] riscv/futex: Bound number of LL/SC retries in cmpxchg Davidlohr Bueso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox