diff options
-rw-r--r-- | arch/arm/kernel/signal.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal.c | 4 | ||||
-rw-r--r-- | arch/x86/entry/common.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 2 | ||||
-rw-r--r-- | include/linux/sched.h | 18 | ||||
-rw-r--r-- | kernel/rseq.c | 7 |
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 | ||
1802 | void __rseq_handle_notify_resume(struct pt_regs *regs); | 1802 | void __rseq_handle_notify_resume(struct ksignal *sig, struct pt_regs *regs); |
1803 | 1803 | ||
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) | ||
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 | ||
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) | ||
1811 | { | 1813 | { |
1812 | preempt_disable(); | 1814 | preempt_disable(); |
1813 | __set_bit(RSEQ_EVENT_SIGNAL_BIT, ¤t->rseq_event_mask); | 1815 | __set_bit(RSEQ_EVENT_SIGNAL_BIT, ¤t->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) | |||
1861 | static inline void rseq_set_notify_resume(struct task_struct *t) | 1863 | static inline void rseq_set_notify_resume(struct task_struct *t) |
1862 | { | 1864 | { |
1863 | } | 1865 | } |
1864 | 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) | ||
1865 | { | 1868 | { |
1866 | } | 1869 | } |
1867 | 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) | ||
1868 | { | 1872 | { |
1869 | } | 1873 | } |
1870 | static inline void rseq_preempt(struct task_struct *t) | 1874 | static 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 | */ |
254 | void __rseq_handle_notify_resume(struct pt_regs *regs) | 254 | void __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 | ||
270 | error: | 270 | error: |
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 |