Skip to content

Commit 1d17e80

Browse files
committed
Merge tag 'core-rseq-2025-09-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull rseq updates from Thomas Gleixner: "Two fixes for RSEQ: - Protect the event mask modification against the membarrier() IPI as otherwise the RmW operation is unprotected and events might be lost - Fix the weak symbol reference in rseq selftests The current weak RSEQ symbols definitions which were added to allow static linkage are not working correctly as they effectively re-define the glibc symbols leading to multiple versions of the symbols when compiled with -fno-common. Mark them as 'extern' to convert them from weak symbol definitions to weak symbol references. That works with static and dynamic linkage independent of -fcommon and -fno-common" * tag 'core-rseq-2025-09-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: rseq/selftests: Use weak symbol reference, not definition, to link with glibc rseq: Protect event mask against membarrier IPI
2 parents 7601d18 + a001cd2 commit 1d17e80

3 files changed

Lines changed: 17 additions & 12 deletions

File tree

include/linux/rseq.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
#include <linux/preempt.h>
88
#include <linux/sched.h>
99

10+
#ifdef CONFIG_MEMBARRIER
11+
# define RSEQ_EVENT_GUARD irq
12+
#else
13+
# define RSEQ_EVENT_GUARD preempt
14+
#endif
15+
1016
/*
1117
* Map the event mask on the user-space ABI enum rseq_cs_flags
1218
* for direct mask checks.
@@ -41,9 +47,8 @@ static inline void rseq_handle_notify_resume(struct ksignal *ksig,
4147
static inline void rseq_signal_deliver(struct ksignal *ksig,
4248
struct pt_regs *regs)
4349
{
44-
preempt_disable();
45-
__set_bit(RSEQ_EVENT_SIGNAL_BIT, &current->rseq_event_mask);
46-
preempt_enable();
50+
scoped_guard(RSEQ_EVENT_GUARD)
51+
__set_bit(RSEQ_EVENT_SIGNAL_BIT, &current->rseq_event_mask);
4752
rseq_handle_notify_resume(ksig, regs);
4853
}
4954

kernel/rseq.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,12 @@ static int rseq_need_restart(struct task_struct *t, u32 cs_flags)
342342

343343
/*
344344
* Load and clear event mask atomically with respect to
345-
* scheduler preemption.
345+
* scheduler preemption and membarrier IPIs.
346346
*/
347-
preempt_disable();
348-
event_mask = t->rseq_event_mask;
349-
t->rseq_event_mask = 0;
350-
preempt_enable();
347+
scoped_guard(RSEQ_EVENT_GUARD) {
348+
event_mask = t->rseq_event_mask;
349+
t->rseq_event_mask = 0;
350+
}
351351

352352
return !!event_mask;
353353
}

tools/testing/selftests/rseq/rseq.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
* Define weak versions to play nice with binaries that are statically linked
4141
* against a libc that doesn't support registering its own rseq.
4242
*/
43-
__weak ptrdiff_t __rseq_offset;
44-
__weak unsigned int __rseq_size;
45-
__weak unsigned int __rseq_flags;
43+
extern __weak ptrdiff_t __rseq_offset;
44+
extern __weak unsigned int __rseq_size;
45+
extern __weak unsigned int __rseq_flags;
4646

4747
static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset;
4848
static const unsigned int *libc_rseq_size_p = &__rseq_size;
@@ -209,7 +209,7 @@ void rseq_init(void)
209209
* libc not having registered a restartable sequence. Try to find the
210210
* symbols if that's the case.
211211
*/
212-
if (!*libc_rseq_size_p) {
212+
if (!libc_rseq_size_p || !*libc_rseq_size_p) {
213213
libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
214214
libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
215215
libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");

0 commit comments

Comments
 (0)