aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sched.h6
-rw-r--r--kernel/ptrace.c12
-rw-r--r--kernel/signal.c90
3 files changed, 75 insertions, 33 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 5157bd9eee37..8bd84b83a35b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1810,17 +1810,21 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
1810#define JOBCTL_STOP_DEQUEUED_BIT 16 /* stop signal dequeued */ 1810#define JOBCTL_STOP_DEQUEUED_BIT 16 /* stop signal dequeued */
1811#define JOBCTL_STOP_PENDING_BIT 17 /* task should stop for group stop */ 1811#define JOBCTL_STOP_PENDING_BIT 17 /* task should stop for group stop */
1812#define JOBCTL_STOP_CONSUME_BIT 18 /* consume group stop count */ 1812#define JOBCTL_STOP_CONSUME_BIT 18 /* consume group stop count */
1813#define JOBCTL_TRAP_STOP_BIT 19 /* trap for STOP */
1813#define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */ 1814#define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */
1814 1815
1815#define JOBCTL_STOP_DEQUEUED (1 << JOBCTL_STOP_DEQUEUED_BIT) 1816#define JOBCTL_STOP_DEQUEUED (1 << JOBCTL_STOP_DEQUEUED_BIT)
1816#define JOBCTL_STOP_PENDING (1 << JOBCTL_STOP_PENDING_BIT) 1817#define JOBCTL_STOP_PENDING (1 << JOBCTL_STOP_PENDING_BIT)
1817#define JOBCTL_STOP_CONSUME (1 << JOBCTL_STOP_CONSUME_BIT) 1818#define JOBCTL_STOP_CONSUME (1 << JOBCTL_STOP_CONSUME_BIT)
1819#define JOBCTL_TRAP_STOP (1 << JOBCTL_TRAP_STOP_BIT)
1818#define JOBCTL_TRAPPING (1 << JOBCTL_TRAPPING_BIT) 1820#define JOBCTL_TRAPPING (1 << JOBCTL_TRAPPING_BIT)
1819 1821
1820#define JOBCTL_PENDING_MASK JOBCTL_STOP_PENDING 1822#define JOBCTL_TRAP_MASK JOBCTL_TRAP_STOP
1823#define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK)
1821 1824
1822extern bool task_set_jobctl_pending(struct task_struct *task, 1825extern bool task_set_jobctl_pending(struct task_struct *task,
1823 unsigned int mask); 1826 unsigned int mask);
1827extern void task_clear_jobctl_trapping(struct task_struct *task);
1824extern void task_clear_jobctl_pending(struct task_struct *task, 1828extern void task_clear_jobctl_pending(struct task_struct *task,
1825 unsigned int mask); 1829 unsigned int mask);
1826 1830
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 7f05f3a1267b..45a8a4c5d8b2 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -83,6 +83,13 @@ void __ptrace_unlink(struct task_struct *child)
83 spin_lock(&child->sighand->siglock); 83 spin_lock(&child->sighand->siglock);
84 84
85 /* 85 /*
86 * Clear all pending traps and TRAPPING. TRAPPING should be
87 * cleared regardless of JOBCTL_STOP_PENDING. Do it explicitly.
88 */
89 task_clear_jobctl_pending(child, JOBCTL_TRAP_MASK);
90 task_clear_jobctl_trapping(child);
91
92 /*
86 * Reinstate JOBCTL_STOP_PENDING if group stop is in effect and 93 * Reinstate JOBCTL_STOP_PENDING if group stop is in effect and
87 * @child isn't dead. 94 * @child isn't dead.
88 */ 95 */
@@ -246,7 +253,7 @@ static int ptrace_attach(struct task_struct *task)
246 spin_lock(&task->sighand->siglock); 253 spin_lock(&task->sighand->siglock);
247 254
248 /* 255 /*
249 * If the task is already STOPPED, set JOBCTL_STOP_PENDING and 256 * If the task is already STOPPED, set JOBCTL_TRAP_STOP and
250 * TRAPPING, and kick it so that it transits to TRACED. TRAPPING 257 * TRAPPING, and kick it so that it transits to TRACED. TRAPPING
251 * will be cleared if the child completes the transition or any 258 * will be cleared if the child completes the transition or any
252 * event which clears the group stop states happens. We'll wait 259 * event which clears the group stop states happens. We'll wait
@@ -263,8 +270,7 @@ static int ptrace_attach(struct task_struct *task)
263 * in and out of STOPPED are protected by siglock. 270 * in and out of STOPPED are protected by siglock.
264 */ 271 */
265 if (task_is_stopped(task) && 272 if (task_is_stopped(task) &&
266 task_set_jobctl_pending(task, 273 task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING))
267 JOBCTL_STOP_PENDING | JOBCTL_TRAPPING))
268 signal_wake_up(task, 1); 274 signal_wake_up(task, 1);
269 275
270 spin_unlock(&task->sighand->siglock); 276 spin_unlock(&task->sighand->siglock);
diff --git a/kernel/signal.c b/kernel/signal.c
index c99b8b5c0be7..b5f55ca1f43f 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -266,7 +266,7 @@ bool task_set_jobctl_pending(struct task_struct *task, unsigned int mask)
266 * CONTEXT: 266 * CONTEXT:
267 * Must be called with @task->sighand->siglock held. 267 * Must be called with @task->sighand->siglock held.
268 */ 268 */
269static void task_clear_jobctl_trapping(struct task_struct *task) 269void task_clear_jobctl_trapping(struct task_struct *task)
270{ 270{
271 if (unlikely(task->jobctl & JOBCTL_TRAPPING)) { 271 if (unlikely(task->jobctl & JOBCTL_TRAPPING)) {
272 task->jobctl &= ~JOBCTL_TRAPPING; 272 task->jobctl &= ~JOBCTL_TRAPPING;
@@ -1790,13 +1790,16 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1790 /* 1790 /*
1791 * If @why is CLD_STOPPED, we're trapping to participate in a group 1791 * If @why is CLD_STOPPED, we're trapping to participate in a group
1792 * stop. Do the bookkeeping. Note that if SIGCONT was delievered 1792 * stop. Do the bookkeeping. Note that if SIGCONT was delievered
1793 * while siglock was released for the arch hook, PENDING could be 1793 * across siglock relocks since INTERRUPT was scheduled, PENDING
1794 * clear now. We act as if SIGCONT is received after TASK_TRACED 1794 * could be clear now. We act as if SIGCONT is received after
1795 * is entered - ignore it. 1795 * TASK_TRACED is entered - ignore it.
1796 */ 1796 */
1797 if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING)) 1797 if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING))
1798 gstop_done = task_participate_group_stop(current); 1798 gstop_done = task_participate_group_stop(current);
1799 1799
1800 /* any trap clears pending STOP trap */
1801 task_clear_jobctl_pending(current, JOBCTL_TRAP_STOP);
1802
1800 /* entering a trap, clear TRAPPING */ 1803 /* entering a trap, clear TRAPPING */
1801 task_clear_jobctl_trapping(current); 1804 task_clear_jobctl_trapping(current);
1802 1805
@@ -1888,13 +1891,30 @@ void ptrace_notify(int exit_code)
1888 spin_unlock_irq(&current->sighand->siglock); 1891 spin_unlock_irq(&current->sighand->siglock);
1889} 1892}
1890 1893
1891/* 1894/**
1892 * This performs the stopping for SIGSTOP and other stop signals. 1895 * do_signal_stop - handle group stop for SIGSTOP and other stop signals
1893 * We have to stop all threads in the thread group. 1896 * @signr: signr causing group stop if initiating
1894 * Returns non-zero if we've actually stopped and released the siglock. 1897 *
1895 * Returns zero if we didn't stop and still hold the siglock. 1898 * If %JOBCTL_STOP_PENDING is not set yet, initiate group stop with @signr
1899 * and participate in it. If already set, participate in the existing
1900 * group stop. If participated in a group stop (and thus slept), %true is
1901 * returned with siglock released.
1902 *
1903 * If ptraced, this function doesn't handle stop itself. Instead,
1904 * %JOBCTL_TRAP_STOP is scheduled and %false is returned with siglock
1905 * untouched. The caller must ensure that INTERRUPT trap handling takes
1906 * places afterwards.
1907 *
1908 * CONTEXT:
1909 * Must be called with @current->sighand->siglock held, which is released
1910 * on %true return.
1911 *
1912 * RETURNS:
1913 * %false if group stop is already cancelled or ptrace trap is scheduled.
1914 * %true if participated in group stop.
1896 */ 1915 */
1897static int do_signal_stop(int signr) 1916static bool do_signal_stop(int signr)
1917 __releases(&current->sighand->siglock)
1898{ 1918{
1899 struct signal_struct *sig = current->signal; 1919 struct signal_struct *sig = current->signal;
1900 1920
@@ -1907,7 +1927,7 @@ static int do_signal_stop(int signr)
1907 1927
1908 if (!likely(current->jobctl & JOBCTL_STOP_DEQUEUED) || 1928 if (!likely(current->jobctl & JOBCTL_STOP_DEQUEUED) ||
1909 unlikely(signal_group_exit(sig))) 1929 unlikely(signal_group_exit(sig)))
1910 return 0; 1930 return false;
1911 /* 1931 /*
1912 * There is no group stop already in progress. We must 1932 * There is no group stop already in progress. We must
1913 * initiate one now. 1933 * initiate one now.
@@ -1951,7 +1971,7 @@ static int do_signal_stop(int signr)
1951 } 1971 }
1952 } 1972 }
1953 } 1973 }
1954retry: 1974
1955 if (likely(!task_ptrace(current))) { 1975 if (likely(!task_ptrace(current))) {
1956 int notify = 0; 1976 int notify = 0;
1957 1977
@@ -1983,27 +2003,33 @@ retry:
1983 2003
1984 /* Now we don't run again until woken by SIGCONT or SIGKILL */ 2004 /* Now we don't run again until woken by SIGCONT or SIGKILL */
1985 schedule(); 2005 schedule();
1986 2006 return true;
1987 spin_lock_irq(&current->sighand->siglock);
1988 } else { 2007 } else {
1989 ptrace_stop(current->jobctl & JOBCTL_STOP_SIGMASK, 2008 /*
1990 CLD_STOPPED, 0, NULL); 2009 * While ptraced, group stop is handled by STOP trap.
1991 current->exit_code = 0; 2010 * Schedule it and let the caller deal with it.
1992 } 2011 */
1993 2012 task_set_jobctl_pending(current, JOBCTL_TRAP_STOP);
1994 /* 2013 return false;
1995 * JOBCTL_STOP_PENDING could be set if another group stop has
1996 * started since being woken up or ptrace wants us to transit
1997 * between TASK_STOPPED and TRACED. Retry group stop.
1998 */
1999 if (current->jobctl & JOBCTL_STOP_PENDING) {
2000 WARN_ON_ONCE(!(current->jobctl & JOBCTL_STOP_SIGMASK));
2001 goto retry;
2002 } 2014 }
2015}
2003 2016
2004 spin_unlock_irq(&current->sighand->siglock); 2017/**
2018 * do_jobctl_trap - take care of ptrace jobctl traps
2019 *
2020 * It is currently used only to trap for group stop while ptraced.
2021 *
2022 * CONTEXT:
2023 * Must be called with @current->sighand->siglock held, which may be
2024 * released and re-acquired before returning with intervening sleep.
2025 */
2026static void do_jobctl_trap(void)
2027{
2028 int signr = current->jobctl & JOBCTL_STOP_SIGMASK;
2005 2029
2006 return 1; 2030 WARN_ON_ONCE(!signr);
2031 ptrace_stop(signr, CLD_STOPPED, 0, NULL);
2032 current->exit_code = 0;
2007} 2033}
2008 2034
2009static int ptrace_signal(int signr, siginfo_t *info, 2035static int ptrace_signal(int signr, siginfo_t *info,
@@ -2110,6 +2136,12 @@ relock:
2110 do_signal_stop(0)) 2136 do_signal_stop(0))
2111 goto relock; 2137 goto relock;
2112 2138
2139 if (unlikely(current->jobctl & JOBCTL_TRAP_MASK)) {
2140 do_jobctl_trap();
2141 spin_unlock_irq(&sighand->siglock);
2142 goto relock;
2143 }
2144
2113 signr = dequeue_signal(current, &current->blocked, info); 2145 signr = dequeue_signal(current, &current->blocked, info);
2114 2146
2115 if (!signr) 2147 if (!signr)