diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-24 08:18:19 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-24 08:18:19 -0400 |
| commit | 2ce413ec1694eca3a4fa738b6d9007c728a0d40a (patch) | |
| tree | 427f27f51f48d40980b304f7e181771688dc4def /include/linux | |
| parent | 64dd76559d4ba281f020af7c87f16071394d1f70 (diff) | |
| parent | 784e0300fe9fe4aa81bd7df9d59e138f56bb605b (diff) | |
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
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/sched.h | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 87bf02d93a27..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. */ |
| @@ -1831,9 +1833,7 @@ static inline void rseq_migrate(struct task_struct *t) | |||
| 1831 | 1833 | ||
| 1832 | /* | 1834 | /* |
| 1833 | * If parent process has a registered restartable sequences area, the | 1835 | * If parent process has a registered restartable sequences area, the |
| 1834 | * child inherits. Only applies when forking a process, not a thread. In | 1836 | * child inherits. Only applies when forking a process, not a thread. |
| 1835 | * case a parent fork() in the middle of a restartable sequence, set the | ||
| 1836 | * resume notifier to force the child to retry. | ||
| 1837 | */ | 1837 | */ |
| 1838 | static inline void rseq_fork(struct task_struct *t, unsigned long clone_flags) | 1838 | static inline void rseq_fork(struct task_struct *t, unsigned long clone_flags) |
| 1839 | { | 1839 | { |
| @@ -1847,7 +1847,6 @@ static inline void rseq_fork(struct task_struct *t, unsigned long clone_flags) | |||
| 1847 | t->rseq_len = current->rseq_len; | 1847 | t->rseq_len = current->rseq_len; |
| 1848 | t->rseq_sig = current->rseq_sig; | 1848 | t->rseq_sig = current->rseq_sig; |
| 1849 | t->rseq_event_mask = current->rseq_event_mask; | 1849 | t->rseq_event_mask = current->rseq_event_mask; |
| 1850 | rseq_preempt(t); | ||
| 1851 | } | 1850 | } |
| 1852 | } | 1851 | } |
| 1853 | 1852 | ||
| @@ -1864,10 +1863,12 @@ static inline void rseq_execve(struct task_struct *t) | |||
| 1864 | static inline void rseq_set_notify_resume(struct task_struct *t) | 1863 | static inline void rseq_set_notify_resume(struct task_struct *t) |
| 1865 | { | 1864 | { |
| 1866 | } | 1865 | } |
| 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) | ||
| 1868 | { | 1868 | { |
| 1869 | } | 1869 | } |
| 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) | ||
| 1871 | { | 1872 | { |
| 1872 | } | 1873 | } |
| 1873 | static inline void rseq_preempt(struct task_struct *t) | 1874 | static inline void rseq_preempt(struct task_struct *t) |
