aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/signal.c4
-rw-r--r--arch/powerpc/kernel/signal.c4
-rw-r--r--arch/x86/entry/common.c2
-rw-r--r--arch/x86/kernel/signal.c2
-rw-r--r--include/linux/sched.h18
-rw-r--r--kernel/rseq.c7
6 files changed, 21 insertions, 16 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index f09e9d66d605..dec130e7078c 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -544,7 +544,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
544 * Increment event counter and perform fixup for the pre-signal 544 * Increment event counter and perform fixup for the pre-signal
545 * frame. 545 * frame.
546 */ 546 */
547 rseq_signal_deliver(regs); 547 rseq_signal_deliver(ksig, regs);
548 548
549 /* 549 /*
550 * Set up the stack frame 550 * Set up the stack frame
@@ -666,7 +666,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
666 } else { 666 } else {
667 clear_thread_flag(TIF_NOTIFY_RESUME); 667 clear_thread_flag(TIF_NOTIFY_RESUME);
668 tracehook_notify_resume(regs); 668 tracehook_notify_resume(regs);
669 rseq_handle_notify_resume(regs); 669 rseq_handle_notify_resume(NULL, regs);
670 } 670 }
671 } 671 }
672 local_irq_disable(); 672 local_irq_disable();
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 17fe4339ba59..b3e8db376ecd 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -134,7 +134,7 @@ static void do_signal(struct task_struct *tsk)
134 /* Re-enable the breakpoints for the signal stack */ 134 /* Re-enable the breakpoints for the signal stack */
135 thread_change_pc(tsk, tsk->thread.regs); 135 thread_change_pc(tsk, tsk->thread.regs);
136 136
137 rseq_signal_deliver(tsk->thread.regs); 137 rseq_signal_deliver(&ksig, tsk->thread.regs);
138 138
139 if (is32) { 139 if (is32) {
140 if (ksig.ka.sa.sa_flags & SA_SIGINFO) 140 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)
170 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 170 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
171 clear_thread_flag(TIF_NOTIFY_RESUME); 171 clear_thread_flag(TIF_NOTIFY_RESUME);
172 tracehook_notify_resume(regs); 172 tracehook_notify_resume(regs);
173 rseq_handle_notify_resume(regs); 173 rseq_handle_notify_resume(NULL, regs);
174 } 174 }
175 175
176 user_enter(); 176 user_enter();
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 92190879b228..3b2490b81918 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -164,7 +164,7 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags)
164 if (cached_flags & _TIF_NOTIFY_RESUME) { 164 if (cached_flags & _TIF_NOTIFY_RESUME) {
165 clear_thread_flag(TIF_NOTIFY_RESUME); 165 clear_thread_flag(TIF_NOTIFY_RESUME);
166 tracehook_notify_resume(regs); 166 tracehook_notify_resume(regs);
167 rseq_handle_notify_resume(regs); 167 rseq_handle_notify_resume(NULL, regs);
168 } 168 }
169 169
170 if (cached_flags & _TIF_USER_RETURN_NOTIFY) 170 if (cached_flags & _TIF_USER_RETURN_NOTIFY)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 445ca11ff863..92a3b312a53c 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -692,7 +692,7 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
692 * Increment event counter and perform fixup for the pre-signal 692 * Increment event counter and perform fixup for the pre-signal
693 * frame. 693 * frame.
694 */ 694 */
695 rseq_signal_deliver(regs); 695 rseq_signal_deliver(ksig, regs);
696 696
697 /* Set up the stack frame */ 697 /* Set up the stack frame */
698 if (is_ia32_frame(ksig)) { 698 if (is_ia32_frame(ksig)) {
diff --git a/include/linux/sched.h b/include/linux/sched.h
index c1882643d455..9256118bd40c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1799,20 +1799,22 @@ static inline void rseq_set_notify_resume(struct task_struct *t)
1799 set_tsk_thread_flag(t, TIF_NOTIFY_RESUME); 1799 set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
1800} 1800}
1801 1801
1802void __rseq_handle_notify_resume(struct pt_regs *regs); 1802void __rseq_handle_notify_resume(struct ksignal *sig, struct pt_regs *regs);
1803 1803
1804static inline void rseq_handle_notify_resume(struct pt_regs *regs) 1804static inline void rseq_handle_notify_resume(struct ksignal *ksig,
1805 struct pt_regs *regs)
1805{ 1806{
1806 if (current->rseq) 1807 if (current->rseq)
1807 __rseq_handle_notify_resume(regs); 1808 __rseq_handle_notify_resume(ksig, regs);
1808} 1809}
1809 1810
1810static inline void rseq_signal_deliver(struct pt_regs *regs) 1811static inline void rseq_signal_deliver(struct ksignal *ksig,
1812 struct pt_regs *regs)
1811{ 1813{
1812 preempt_disable(); 1814 preempt_disable();
1813 __set_bit(RSEQ_EVENT_SIGNAL_BIT, &current->rseq_event_mask); 1815 __set_bit(RSEQ_EVENT_SIGNAL_BIT, &current->rseq_event_mask);
1814 preempt_enable(); 1816 preempt_enable();
1815 rseq_handle_notify_resume(regs); 1817 rseq_handle_notify_resume(ksig, regs);
1816} 1818}
1817 1819
1818/* rseq_preempt() requires preemption to be disabled. */ 1820/* rseq_preempt() requires preemption to be disabled. */
@@ -1861,10 +1863,12 @@ static inline void rseq_execve(struct task_struct *t)
1861static inline void rseq_set_notify_resume(struct task_struct *t) 1863static inline void rseq_set_notify_resume(struct task_struct *t)
1862{ 1864{
1863} 1865}
1864static inline void rseq_handle_notify_resume(struct pt_regs *regs) 1866static inline void rseq_handle_notify_resume(struct ksignal *ksig,
1867 struct pt_regs *regs)
1865{ 1868{
1866} 1869}
1867static inline void rseq_signal_deliver(struct pt_regs *regs) 1870static inline void rseq_signal_deliver(struct ksignal *ksig,
1871 struct pt_regs *regs)
1868{ 1872{
1869} 1873}
1870static inline void rseq_preempt(struct task_struct *t) 1874static inline void rseq_preempt(struct task_struct *t)
diff --git a/kernel/rseq.c b/kernel/rseq.c
index ae306f90c514..22b6acf1ad63 100644
--- a/kernel/rseq.c
+++ b/kernel/rseq.c
@@ -251,10 +251,10 @@ static int rseq_ip_fixup(struct pt_regs *regs)
251 * respect to other threads scheduled on the same CPU, and with respect 251 * respect to other threads scheduled on the same CPU, and with respect
252 * to signal handlers. 252 * to signal handlers.
253 */ 253 */
254void __rseq_handle_notify_resume(struct pt_regs *regs) 254void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
255{ 255{
256 struct task_struct *t = current; 256 struct task_struct *t = current;
257 int ret; 257 int ret, sig;
258 258
259 if (unlikely(t->flags & PF_EXITING)) 259 if (unlikely(t->flags & PF_EXITING))
260 return; 260 return;
@@ -268,7 +268,8 @@ void __rseq_handle_notify_resume(struct pt_regs *regs)
268 return; 268 return;
269 269
270error: 270error:
271 force_sig(SIGSEGV, t); 271 sig = ksig ? ksig->sig : 0;
272 force_sigsegv(sig, t);
272} 273}
273 274
274#ifdef CONFIG_DEBUG_RSEQ 275#ifdef CONFIG_DEBUG_RSEQ