Skip to content

Commit 2ce413e

Browse files
committed
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull rseq fixes from Thomas Gleixer: "A pile of rseq related fixups: - Prevent infinite recursion when delivering SIGSEGV - Remove the abort of rseq critical section on fork() as syscalls inside rseq critical sections are explicitely forbidden. So no point in doing the abort on the child. - Align the rseq structure on 32 bytes in the ARM selftest code. - Fix file permissions of the test script" * 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: rseq: Avoid infinite recursion when delivering SIGSEGV rseq/cleanup: Do not abort rseq c.s. in child on fork() rseq/selftests/arm: Align 'struct rseq_cs' on 32 bytes rseq/selftests: Make run_param_test.sh executable
2 parents 64dd765 + 784e030 commit 2ce413e

File tree

8 files changed

+23
-20
lines changed

8 files changed

+23
-20
lines changed

arch/arm/kernel/signal.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
544544
* Increment event counter and perform fixup for the pre-signal
545545
* frame.
546546
*/
547-
rseq_signal_deliver(regs);
547+
rseq_signal_deliver(ksig, regs);
548548

549549
/*
550550
* Set up the stack frame
@@ -666,7 +666,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
666666
} else {
667667
clear_thread_flag(TIF_NOTIFY_RESUME);
668668
tracehook_notify_resume(regs);
669-
rseq_handle_notify_resume(regs);
669+
rseq_handle_notify_resume(NULL, regs);
670670
}
671671
}
672672
local_irq_disable();

arch/powerpc/kernel/signal.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ static void do_signal(struct task_struct *tsk)
134134
/* Re-enable the breakpoints for the signal stack */
135135
thread_change_pc(tsk, tsk->thread.regs);
136136

137-
rseq_signal_deliver(tsk->thread.regs);
137+
rseq_signal_deliver(&ksig, tsk->thread.regs);
138138

139139
if (is32) {
140140
if (ksig.ka.sa.sa_flags & SA_SIGINFO)
@@ -170,7 +170,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
170170
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
171171
clear_thread_flag(TIF_NOTIFY_RESUME);
172172
tracehook_notify_resume(regs);
173-
rseq_handle_notify_resume(regs);
173+
rseq_handle_notify_resume(NULL, regs);
174174
}
175175

176176
user_enter();

arch/x86/entry/common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags)
164164
if (cached_flags & _TIF_NOTIFY_RESUME) {
165165
clear_thread_flag(TIF_NOTIFY_RESUME);
166166
tracehook_notify_resume(regs);
167-
rseq_handle_notify_resume(regs);
167+
rseq_handle_notify_resume(NULL, regs);
168168
}
169169

170170
if (cached_flags & _TIF_USER_RETURN_NOTIFY)

arch/x86/kernel/signal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
692692
* Increment event counter and perform fixup for the pre-signal
693693
* frame.
694694
*/
695-
rseq_signal_deliver(regs);
695+
rseq_signal_deliver(ksig, regs);
696696

697697
/* Set up the stack frame */
698698
if (is_ia32_frame(ksig)) {

include/linux/sched.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,20 +1799,22 @@ static inline void rseq_set_notify_resume(struct task_struct *t)
17991799
set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
18001800
}
18011801

1802-
void __rseq_handle_notify_resume(struct pt_regs *regs);
1802+
void __rseq_handle_notify_resume(struct ksignal *sig, struct pt_regs *regs);
18031803

1804-
static inline void rseq_handle_notify_resume(struct pt_regs *regs)
1804+
static inline void rseq_handle_notify_resume(struct ksignal *ksig,
1805+
struct pt_regs *regs)
18051806
{
18061807
if (current->rseq)
1807-
__rseq_handle_notify_resume(regs);
1808+
__rseq_handle_notify_resume(ksig, regs);
18081809
}
18091810

1810-
static inline void rseq_signal_deliver(struct pt_regs *regs)
1811+
static inline void rseq_signal_deliver(struct ksignal *ksig,
1812+
struct pt_regs *regs)
18111813
{
18121814
preempt_disable();
18131815
__set_bit(RSEQ_EVENT_SIGNAL_BIT, &current->rseq_event_mask);
18141816
preempt_enable();
1815-
rseq_handle_notify_resume(regs);
1817+
rseq_handle_notify_resume(ksig, regs);
18161818
}
18171819

18181820
/* rseq_preempt() requires preemption to be disabled. */
@@ -1831,9 +1833,7 @@ static inline void rseq_migrate(struct task_struct *t)
18311833

18321834
/*
18331835
* If parent process has a registered restartable sequences area, the
1834-
* child inherits. Only applies when forking a process, not a thread. In
1835-
* case a parent fork() in the middle of a restartable sequence, set the
1836-
* resume notifier to force the child to retry.
1836+
* child inherits. Only applies when forking a process, not a thread.
18371837
*/
18381838
static inline void rseq_fork(struct task_struct *t, unsigned long clone_flags)
18391839
{
@@ -1847,7 +1847,6 @@ static inline void rseq_fork(struct task_struct *t, unsigned long clone_flags)
18471847
t->rseq_len = current->rseq_len;
18481848
t->rseq_sig = current->rseq_sig;
18491849
t->rseq_event_mask = current->rseq_event_mask;
1850-
rseq_preempt(t);
18511850
}
18521851
}
18531852

@@ -1864,10 +1863,12 @@ static inline void rseq_execve(struct task_struct *t)
18641863
static inline void rseq_set_notify_resume(struct task_struct *t)
18651864
{
18661865
}
1867-
static inline void rseq_handle_notify_resume(struct pt_regs *regs)
1866+
static inline void rseq_handle_notify_resume(struct ksignal *ksig,
1867+
struct pt_regs *regs)
18681868
{
18691869
}
1870-
static inline void rseq_signal_deliver(struct pt_regs *regs)
1870+
static inline void rseq_signal_deliver(struct ksignal *ksig,
1871+
struct pt_regs *regs)
18711872
{
18721873
}
18731874
static inline void rseq_preempt(struct task_struct *t)

kernel/rseq.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,10 @@ static int rseq_ip_fixup(struct pt_regs *regs)
251251
* respect to other threads scheduled on the same CPU, and with respect
252252
* to signal handlers.
253253
*/
254-
void __rseq_handle_notify_resume(struct pt_regs *regs)
254+
void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
255255
{
256256
struct task_struct *t = current;
257-
int ret;
257+
int ret, sig;
258258

259259
if (unlikely(t->flags & PF_EXITING))
260260
return;
@@ -268,7 +268,8 @@ void __rseq_handle_notify_resume(struct pt_regs *regs)
268268
return;
269269

270270
error:
271-
force_sig(SIGSEGV, t);
271+
sig = ksig ? ksig->sig : 0;
272+
force_sigsegv(sig, t);
272273
}
273274

274275
#ifdef CONFIG_DEBUG_RSEQ

tools/testing/selftests/rseq/rseq-arm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ do { \
5757
#define __RSEQ_ASM_DEFINE_ABORT(table_label, label, teardown, \
5858
abort_label, version, flags, \
5959
start_ip, post_commit_offset, abort_ip) \
60+
".balign 32\n\t" \
6061
__rseq_str(table_label) ":\n\t" \
6162
".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
6263
".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \

tools/testing/selftests/rseq/run_param_test.sh

100644100755
File mode changed.

0 commit comments

Comments
 (0)