diff options
author | Josh Boyer <jwboyer@redhat.com> | 2012-01-25 16:48:32 -0500 |
---|---|---|
committer | Josh Boyer <jwboyer@redhat.com> | 2012-01-25 16:48:32 -0500 |
commit | 62e9e5ab948df1986d0c054176b6712e1475d9a3 (patch) | |
tree | 710777d4c1840f4837cdbe0ec463b3fa57420b12 | |
parent | 64d09e6b046b02d725ba859b728c6f22c4a08dee (diff) | |
download | kernel-62e9e5ab948df1986d0c054176b6712e1475d9a3.tar.gz kernel-62e9e5ab948df1986d0c054176b6712e1475d9a3.tar.xz kernel-62e9e5ab948df1986d0c054176b6712e1475d9a3.zip |
Update utrace.patch from Oleg Nesterov
-rw-r--r-- | kernel.spec | 7 | ||||
-rw-r--r-- | utrace.patch | 4295 |
2 files changed, 904 insertions, 3398 deletions
diff --git a/kernel.spec b/kernel.spec index ce5061df7..9d029d222 100644 --- a/kernel.spec +++ b/kernel.spec @@ -54,7 +54,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 1 +%global baserelease 2 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -1417,7 +1417,7 @@ ApplyPatch revert-efi-rtclock.patch ApplyPatch efi-dont-map-boot-services-on-32bit.patch # utrace. -# pplyPatch utrace.patch +ApplyPatch utrace.patch ApplyPatch ext4-Support-check-none-nocheck-mount-options.patch @@ -2266,6 +2266,9 @@ fi # ||----w | # || || %changelog +* Wed Jan 25 2012 Josh Boyer <jwboyer@redhat.com> +- Update utrace.patch from Oleg Nesterov + * Wed Jan 25 2012 Josh Boyer <jwboyer@redhat.com> - 3.3.0-0.rc1.git2.1 - Linux 3.3-rc1-git2 (upstream f8275f9694b8adf9f3498e747ea4c3e8b984499b) diff --git a/utrace.patch b/utrace.patch index 060d351e5..0e34971ca 100644 --- a/utrace.patch +++ b/utrace.patch @@ -1,81 +1,70 @@ -From davej Wed Aug 3 15:16:11 2011 -From oleg@redhat.com Mon Nov 21 15:06:14 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:14 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 9A1F8D50F1; - Mon, 21 Nov 2011 15:06:14 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id gJzpul4rDNnA; Mon, 21 Nov 2011 15:06:14 -0500 (EST) -Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 7DD4BD50EA; - Mon, 21 Nov 2011 15:06:14 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6BJJ022074; - Mon, 21 Nov 2011 15:06:12 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:32 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:30 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 01/33] utrace core -Message-ID: <20111121200130.GA27756@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 -Status: RO -Content-Length: 139951 -Lines: 3867 +utrace for 3.3-rc1 kernel, on top of dcd6c92267155e70a94b3927bce681ce74b80d1f. + +The split-out series is available in the git repository at: + + git@github.com:utrace/linux.git utrace-3.3 + +Oleg Nesterov (31): + utrace: add utrace_init_task/utrace_free_task calls + tracehooks: add utrace hooks + tracehooks: reintroduce tracehook_consider_fatal_signal() + add utrace hooks into sig_ignored() and recalc_sigpending() + restore the EXEC/EXIT/CLONE utrace hooks + utrace: utrace_report_death() can use task_utrace_struct() + restore the DEATH/REAP utrace hooks + utrace: remove jobctl bits + ptrace: take ->siglock around s/TRACED/RUNNING/ + introduce wake_up_quiescent() + introduce ptrace_signal_wake_up() + wait_task_inactive: treat task->state and match_state as bitmasks + introduce TASK_UTRACED state + utrace: use TASK_UTRACED instead of TASK_TRACED + reintroduce tracehook_finish_jctl() as utrace_end_stop() + teach wake_up_quiescent() to do "selective" wake_up + ptrace_stop: do not assume the task is running after wake_up_quiescent() + get_signal_to_deliver: restore/restructure utrace/ptrace signal reporting + utrace_get_signal: s/JOBCTL_STOP_PENDING/JOBCTL_PENDING_MASK/ + introduce ptrace_set_syscall_trace() + introduce PT_SYSCALL_TRACE flag + utrace: don't clear TIF_SYSCALL_TRACE if it is needed by ptrace + introduce task_utrace_lock/task_utrace_unlock + teach ptrace_set_syscall_trace() to play well with utrace + introduce PT_SINGLE_STEP and PT_SINGLE_BLOCK + utrace: finish_resume_report: don't do user_xxx_step() if ptrace_wants_step() + ptrace: shift user_*_step() from ptrace_resume() to ptrace_stop() + ptrace_disable: no need to disable stepping + ptrace_report_syscall: check TIF_SYSCALL_EMU + utrace_resume: check irqs_disabled() to shut up lockdep + utrace: s390: fix the compile problem with traps.c + +Roland McGrath (1): + utrace core + +Tony Breeds (1): + ptrace_report_syscall: check if TIF_SYSCALL_EMU is defined -From: Roland McGrath <roland@redhat.com> - -This adds the utrace facility, a new modular interface in the kernel for -implementing user thread tracing and debugging. This fits on top of the -tracehook_* layer, so the new code is well-isolated. - -The new interface is in <linux/utrace.h> and the DocBook utrace book -describes it. It allows for multiple separate tracing engines to work in -parallel without interfering with each other. Higher-level tracing -facilities can be implemented as loadable kernel modules using this layer. - -The new facility is made optional under CONFIG_UTRACE. -When this is not enabled, no new code is added. -It can only be enabled on machines that have all the -prerequisites and select CONFIG_HAVE_ARCH_TRACEHOOK. - -In this initial version, utrace and ptrace do not play together at all, -the next patches try to fix this. - -This is is same/old utrace-core patch except: - - - use task->jobctl/JOBCTL_STOP_DEQUEUED instead of removed - signal->flags/SIGNAL_STOP_DEQUEUED in utrace_get_signal() - - - do not include the tracehook changes, this comes with the - next patches - -Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Oleg Nesterov <oleg@redhat.com> --- Documentation/DocBook/Makefile | 2 +- Documentation/DocBook/utrace.tmpl | 589 +++++++++ - fs/proc/array.c | 3 + - include/linux/sched.h | 5 + - include/linux/utrace.h | 692 +++++++++++ + arch/s390/kernel/traps.c | 6 +- + arch/x86/kernel/ptrace.c | 1 - + fs/exec.c | 5 +- + fs/proc/array.c | 14 +- + include/linux/ptrace.h | 7 + + include/linux/sched.h | 25 +- + include/linux/signal.h | 2 + + include/linux/tracehook.h | 59 +- + include/linux/utrace.h | 773 ++++++++++++ init/Kconfig | 9 + kernel/Makefile | 1 + - kernel/utrace.c | 2440 +++++++++++++++++++++++++++++++++++++ - 8 files changed, 3740 insertions(+), 1 deletions(-) + kernel/exit.c | 5 + + kernel/fork.c | 9 + + kernel/ptrace.c | 57 +- + kernel/sched/core.c | 2 +- + kernel/signal.c | 97 ++- + kernel/utrace.c | 2462 +++++++++++++++++++++++++++++++++++++ + 19 files changed, 4069 insertions(+), 56 deletions(-) create mode 100644 Documentation/DocBook/utrace.tmpl create mode 100644 include/linux/utrace.h create mode 100644 kernel/utrace.c @@ -688,8 +677,69 @@ index 0000000..0c40add +</chapter> + +</book> +diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c +index 5ce3750..4f0b32f 100644 +--- a/arch/s390/kernel/traps.c ++++ b/arch/s390/kernel/traps.c +@@ -18,7 +18,7 @@ + #include <linux/kernel.h> + #include <linux/string.h> + #include <linux/errno.h> +-#include <linux/ptrace.h> ++#include <linux/tracehook.h> + #include <linux/timer.h> + #include <linux/mm.h> + #include <linux/smp.h> +@@ -330,7 +330,7 @@ void __kprobes do_per_trap(struct pt_regs *regs) + + if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP) + return; +- if (!current->ptrace) ++ if (!tracehook_consider_fatal_signal(current, SIGTRAP)) + return; + info.si_signo = SIGTRAP; + info.si_errno = 0; +@@ -415,7 +415,7 @@ static void __kprobes illegal_op(struct pt_regs *regs) + if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) + return; + if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { +- if (current->ptrace) { ++ if (tracehook_consider_fatal_signal(current, SIGTRAP)) { + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_BRKPT; +diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c +index 5026738..97687f3 100644 +--- a/arch/x86/kernel/ptrace.c ++++ b/arch/x86/kernel/ptrace.c +@@ -809,7 +809,6 @@ static int ioperm_get(struct task_struct *target, + */ + void ptrace_disable(struct task_struct *child) + { +- user_disable_single_step(child); + #ifdef TIF_SYSCALL_EMU + clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); + #endif +diff --git a/fs/exec.c b/fs/exec.c +index aeb135c..36a0cbe 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1401,9 +1401,12 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) + */ + bprm->recursion_depth = depth; + if (retval >= 0) { +- if (depth == 0) ++ if (depth == 0) { ++ UTRACE_HOOK(current, EXEC, ++ report_exec(fmt, bprm, regs)); + ptrace_event(PTRACE_EVENT_EXEC, + old_pid); ++ } + put_binfmt(fmt); + allow_write_access(bprm->file); + if (bprm->file) diff --git a/fs/proc/array.c b/fs/proc/array.c -index 3a1dafd..f0c0ea2 100644 +index c602b8d..a700b78 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -81,6 +81,7 @@ @@ -700,7 +750,25 @@ index 3a1dafd..f0c0ea2 100644 #include <asm/pgtable.h> #include <asm/processor.h> -@@ -192,6 +193,8 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, +@@ -137,11 +138,12 @@ static const char * const task_state_array[] = { + "D (disk sleep)", /* 2 */ + "T (stopped)", /* 4 */ + "t (tracing stop)", /* 8 */ +- "Z (zombie)", /* 16 */ +- "X (dead)", /* 32 */ +- "x (dead)", /* 64 */ +- "K (wakekill)", /* 128 */ +- "W (waking)", /* 256 */ ++ "t (tracing stop)", /* 16 (stopped by utrace) */ ++ "Z (zombie)", /* 32 */ ++ "X (dead)", /* 64 */ ++ "x (dead)", /* 128 */ ++ "K (wakekill)", /* 256 */ ++ "W (waking)", /* 512 */ + }; + + static inline const char *get_task_state(struct task_struct *tsk) +@@ -192,6 +194,8 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, cred->uid, cred->euid, cred->suid, cred->fsuid, cred->gid, cred->egid, cred->sgid, cred->fsgid); @@ -709,11 +777,87 @@ index 3a1dafd..f0c0ea2 100644 task_lock(p); if (p->files) fdt = files_fdtable(p->files); +diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h +index c2f1f6a..236b920 100644 +--- a/include/linux/ptrace.h ++++ b/include/linux/ptrace.h +@@ -104,6 +104,10 @@ + + #define PT_TRACE_MASK 0x000003f4 + ++#define PT_SYSCALL_TRACE 0x00020000 ++#define PT_SINGLE_STEP 0x00040000 ++#define PT_SINGLE_BLOCK 0x00080000 ++ + /* single stepping state bits (used on ARM and PA-RISC) */ + #define PT_SINGLESTEP_BIT 31 + #define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT) +@@ -114,6 +118,7 @@ + #include <linux/sched.h> /* For struct task_struct. */ + #include <linux/err.h> /* for IS_ERR_VALUE */ + ++extern void ptrace_signal_wake_up(struct task_struct *p, int quiescent); + + extern long arch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data); +@@ -228,6 +233,8 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace) + + if (unlikely(ptrace) && current->ptrace) { + child->ptrace = current->ptrace; ++ child->ptrace &= ++ ~(PT_SYSCALL_TRACE | PT_SINGLE_STEP | PT_SINGLE_BLOCK); + __ptrace_link(child, current->parent); + + if (child->ptrace & PT_SEIZED) diff --git a/include/linux/sched.h b/include/linux/sched.h -index 68daf4f..4d45f93 100644 +index 4032ec1..e95c1dc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1403,6 +1403,11 @@ struct task_struct { +@@ -185,16 +185,17 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) + #define TASK_UNINTERRUPTIBLE 2 + #define __TASK_STOPPED 4 + #define __TASK_TRACED 8 ++#define __TASK_UTRACED 16 + /* in tsk->exit_state */ +-#define EXIT_ZOMBIE 16 +-#define EXIT_DEAD 32 ++#define EXIT_ZOMBIE 32 ++#define EXIT_DEAD 64 + /* in tsk->state again */ +-#define TASK_DEAD 64 +-#define TASK_WAKEKILL 128 +-#define TASK_WAKING 256 +-#define TASK_STATE_MAX 512 ++#define TASK_DEAD 128 ++#define TASK_WAKEKILL 256 ++#define TASK_WAKING 512 ++#define TASK_STATE_MAX 1024 + +-#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW" ++#define TASK_STATE_TO_CHAR_STR "RSDTtUZXxKW" + + extern char ___assert_task_state[1 - 2*!!( + sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)]; +@@ -203,15 +204,16 @@ extern char ___assert_task_state[1 - 2*!!( + #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) + #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) + #define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED) ++#define TASK_UTRACED (TASK_WAKEKILL | __TASK_UTRACED) + + /* Convenience macros for the sake of wake_up */ + #define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE) +-#define TASK_ALL (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED) ++#define TASK_ALL (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED | __TASK_UTRACED) + + /* get_task_state() */ + #define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \ + TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \ +- __TASK_TRACED) ++ __TASK_TRACED | __TASK_UTRACED) + + #define task_is_traced(task) ((task->state & __TASK_TRACED) != 0) + #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0) +@@ -1420,6 +1422,11 @@ struct task_struct { #endif seccomp_t seccomp; @@ -725,12 +869,140 @@ index 68daf4f..4d45f93 100644 /* Thread group tracking */ u32 parent_exec_id; u32 self_exec_id; +diff --git a/include/linux/signal.h b/include/linux/signal.h +index 7987ce7..c320549 100644 +--- a/include/linux/signal.h ++++ b/include/linux/signal.h +@@ -239,6 +239,8 @@ static inline int valid_signal(unsigned long sig) + struct timespec; + struct pt_regs; + ++extern int wake_up_quiescent(struct task_struct *p, unsigned int state); ++ + extern int next_signal(struct sigpending *pending, sigset_t *mask); + extern int do_send_sig_info(int sig, struct siginfo *info, + struct task_struct *p, bool group); +diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h +index a71a292..a1bac95 100644 +--- a/include/linux/tracehook.h ++++ b/include/linux/tracehook.h +@@ -49,6 +49,7 @@ + #include <linux/sched.h> + #include <linux/ptrace.h> + #include <linux/security.h> ++#include <linux/utrace.h> + struct linux_binprm; + + /* +@@ -58,8 +59,12 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) + { + int ptrace = current->ptrace; + +- if (!(ptrace & PT_PTRACED)) +- return; ++ if (!(ptrace & PT_SYSCALL_TRACE)) { ++#ifdef TIF_SYSCALL_EMU ++ if (!test_thread_flag(TIF_SYSCALL_EMU)) ++#endif ++ return; ++ } + + ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); + +@@ -96,10 +101,16 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) + static inline __must_check int tracehook_report_syscall_entry( + struct pt_regs *regs) + { ++ if ((task_utrace_flags(current) & UTRACE_EVENT(SYSCALL_ENTRY)) && ++ utrace_report_syscall_entry(regs)) ++ return 1; + ptrace_report_syscall(regs); + return 0; + } + ++#define ptrace_wants_step(task) \ ++ ((task)->ptrace & (PT_SINGLE_STEP | PT_SINGLE_BLOCK)) ++ + /** + * tracehook_report_syscall_exit - task has just finished a system call + * @regs: user register state of current task +@@ -119,7 +130,10 @@ static inline __must_check int tracehook_report_syscall_entry( + */ + static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) + { +- if (step) { ++ if (task_utrace_flags(current) & UTRACE_EVENT(SYSCALL_EXIT)) ++ utrace_report_syscall_exit(regs); ++ ++ if (step && ptrace_wants_step(current)) { + siginfo_t info; + user_single_step_siginfo(current, regs, &info); + force_sig_info(SIGTRAP, &info, current); +@@ -148,10 +162,34 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, + const struct k_sigaction *ka, + struct pt_regs *regs, int stepping) + { +- if (stepping) ++ if (task_utrace_flags(current)) ++ utrace_signal_handler(current, stepping); ++ if (stepping && ptrace_wants_step(current)) + ptrace_notify(SIGTRAP); + } + ++/** ++ * tracehook_consider_fatal_signal - suppress special handling of fatal signal ++ * @task: task receiving the signal ++ * @sig: signal number being sent ++ * ++ * Return nonzero to prevent special handling of this termination signal. ++ * Normally handler for signal is %SIG_DFL. It can be %SIG_IGN if @sig is ++ * ignored, in which case force_sig() is about to reset it to %SIG_DFL. ++ * When this returns zero, this signal might cause a quick termination ++ * that does not give the debugger a chance to intercept the signal. ++ * ++ * Called with or without @task->sighand->siglock held. ++ */ ++static inline int tracehook_consider_fatal_signal(struct task_struct *task, ++ int sig) ++{ ++ if (unlikely(task_utrace_flags(task) & (UTRACE_EVENT(SIGNAL_TERM) | ++ UTRACE_EVENT(SIGNAL_CORE)))) ++ return 1; ++ return task->ptrace != 0; ++} ++ + #ifdef TIF_NOTIFY_RESUME + /** + * set_notify_resume - cause tracehook_notify_resume() to be called +@@ -179,10 +217,21 @@ static inline void set_notify_resume(struct task_struct *task) + * asynchronously, this will be called again before we return to + * user mode. + * +- * Called without locks. ++ * Called without locks. However, on some machines this may be ++ * called with interrupts disabled. + */ + static inline void tracehook_notify_resume(struct pt_regs *regs) + { ++ struct task_struct *task = current; ++ /* ++ * Prevent the following store/load from getting ahead of the ++ * caller which clears TIF_NOTIFY_RESUME. This pairs with the ++ * implicit mb() before setting TIF_NOTIFY_RESUME in ++ * set_notify_resume(). ++ */ ++ smp_mb(); ++ if (task_utrace_flags(task)) ++ utrace_resume(task, regs); + } + #endif /* TIF_NOTIFY_RESUME */ + diff --git a/include/linux/utrace.h b/include/linux/utrace.h new file mode 100644 -index 0000000..f251efe +index 0000000..f37373b --- /dev/null +++ b/include/linux/utrace.h -@@ -0,0 +1,692 @@ +@@ -0,0 +1,773 @@ +/* + * utrace infrastructure interface for debugging user processes + * @@ -832,7 +1104,7 @@ index 0000000..f251efe +void utrace_report_clone(unsigned long, struct task_struct *); +void utrace_finish_vfork(struct task_struct *); +void utrace_report_exit(long *exit_code); -+void utrace_report_death(struct task_struct *, struct utrace *, bool, int); ++void utrace_report_death(struct task_struct *, bool, int); +void utrace_report_jctl(int notify, int type); +void utrace_report_exec(struct linux_binfmt *, struct linux_binprm *, + struct pt_regs *regs); @@ -840,8 +1112,22 @@ index 0000000..f251efe +void utrace_report_syscall_exit(struct pt_regs *); +void utrace_signal_handler(struct task_struct *, int); + ++#define UTRACE_FLAG(task, ev) (task_utrace_flags(task) & UTRACE_EVENT(ev)) ++ ++#define UTRACE_HOOK(task, ev, callback) \ ++ do { \ ++ if (UTRACE_FLAG(task, ev)) \ ++ utrace_ ## callback; \ ++ } while (0) ++ +#ifndef CONFIG_UTRACE + ++static inline void task_utrace_lock(struct task_struct *task) ++{ ++} ++static inline void task_utrace_unlock(struct task_struct *task) ++{ ++} +/* + * <linux/tracehook.h> uses these accessors to avoid #ifdef CONFIG_UTRACE. + */ @@ -864,6 +1150,9 @@ index 0000000..f251efe + +#else /* CONFIG_UTRACE */ + ++extern void task_utrace_lock(struct task_struct *task); ++extern void task_utrace_unlock(struct task_struct *task); ++ +static inline unsigned long task_utrace_flags(struct task_struct *task) +{ + return task->utrace_flags; @@ -1422,14 +1711,78 @@ index 0000000..f251efe + +#endif /* CONFIG_UTRACE */ + ++static inline void utrace_release_task(struct task_struct *task) ++{ ++ /* see utrace_add_engine() about this barrier */ ++ smp_mb(); ++ if (task_utrace_flags(task)) ++ utrace_maybe_reap(task, task_utrace_struct(task), true); ++} ++ ++static inline void utrace_exit_notify(struct task_struct *task, ++ int signal, int group_dead) ++{ ++ /* ++ * If utrace_set_events() was just called to enable ++ * UTRACE_EVENT(DEATH), then we are obliged to call ++ * utrace_report_death() and not miss it. utrace_set_events() ++ * checks @task->exit_state under tasklist_lock to synchronize ++ * with exit_notify(), the caller. ++ */ ++ if (task_utrace_flags(task) & _UTRACE_DEATH_EVENTS) ++ utrace_report_death(task, group_dead, signal); ++} ++ ++/** ++ * utrace_end_stop - report about return from STOPPED/TRACED ++ * ++ * This is called by do_signal_stop() and ptrace_stop after wakeup. ++ */ ++static inline void utrace_end_stop(void) ++{ ++ if (task_utrace_flags(current)) ++ utrace_finish_stop(); ++} ++ ++/** ++ * utrace_hook_signal - deliver synthetic signal to traced task ++ * @task: @current ++ * @regs: task_pt_regs(@current) ++ * @info: details of synthetic signal ++ * @return_ka: sigaction for synthetic signal ++ * ++ * Return zero to check for a real pending signal normally. ++ * Return -1 after releasing the siglock to repeat the check. ++ * Return a signal number to induce an artificial signal delivery, ++ * setting *@info and *@return_ka to specify its details and behavior. ++ * ++ * The @return_ka->sa_handler value controls the disposition of the ++ * signal, no matter the signal number. For %SIG_DFL, the return value ++ * is a representative signal to indicate the behavior (e.g. %SIGTERM ++ * for death, %SIGQUIT for core dump, %SIGSTOP for job control stop, ++ * %SIGTSTP for stop unless in an orphaned pgrp), but the signal number ++ * reported will be @info->si_signo instead. ++ * ++ * Called with @task->sighand->siglock held, before dequeuing pending signals. ++ */ ++static inline int utrace_hook_signal(struct task_struct *task, ++ struct pt_regs *regs, ++ siginfo_t *info, ++ struct k_sigaction *return_ka) ++{ ++ if (unlikely(task_utrace_flags(task))) ++ return utrace_get_signal(task, regs, info, return_ka); ++ return 0; ++} ++ +#endif /* linux/utrace.h */ diff --git a/init/Kconfig b/init/Kconfig -index 43298f9..3f670e5 100644 +index 3f42cd6..5f4f92e 100644 --- a/init/Kconfig +++ b/init/Kconfig -@@ -372,6 +372,15 @@ config AUDIT_TREE - depends on AUDITSYSCALL - select FSNOTIFY +@@ -386,6 +386,15 @@ config AUDIT_LOGINUID_IMMUTABLE + one to drop potentially dangerous capabilites from the login tasks, + but may not be backwards compatible with older init systems. +config UTRACE + bool "Infrastructure for tracing and debugging user processes" @@ -1444,10 +1797,10 @@ index 43298f9..3f670e5 100644 menu "RCU Subsystem" diff --git a/kernel/Makefile b/kernel/Makefile -index e898c5b..e43bbfb 100644 +index 2d9de86..6c6749d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile -@@ -68,6 +68,7 @@ obj-$(CONFIG_IKCONFIG) += configs.o +@@ -67,6 +67,7 @@ obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_RESOURCE_COUNTERS) += res_counter.o obj-$(CONFIG_SMP) += stop_machine.o obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o @@ -1455,12 +1808,418 @@ index e898c5b..e43bbfb 100644 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o +diff --git a/kernel/exit.c b/kernel/exit.c +index 294b170..16108a5 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -169,6 +169,8 @@ void release_task(struct task_struct * p) + struct task_struct *leader; + int zap_leader; + repeat: ++ utrace_release_task(p); ++ + /* don't need to get the RCU readlock here - the process is dead and + * can't be modifying its own credentials. But shut RCU-lockdep up */ + rcu_read_lock(); +@@ -857,6 +859,8 @@ static void exit_notify(struct task_struct *tsk, int group_dead) + wake_up_process(tsk->signal->group_exit_task); + write_unlock_irq(&tasklist_lock); + ++ utrace_exit_notify(tsk, autoreap ? -1 : SIGCHLD, group_dead); ++ + /* If the process is dead, release it - nobody will wait for it */ + if (autoreap) + release_task(tsk); +@@ -910,6 +914,7 @@ void do_exit(long code) + */ + set_fs(USER_DS); + ++ UTRACE_HOOK(current, EXIT, report_exit(&code)); + ptrace_event(PTRACE_EVENT_EXIT, code); + + validate_creds_for_do_exit(tsk); +diff --git a/kernel/fork.c b/kernel/fork.c +index 051f090..e103101 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -66,6 +66,7 @@ + #include <linux/user-return-notifier.h> + #include <linux/oom.h> + #include <linux/khugepaged.h> ++#include <linux/utrace.h> + + #include <asm/pgtable.h> + #include <asm/pgalloc.h> +@@ -169,6 +170,8 @@ void free_task(struct task_struct *tsk) + free_thread_info(tsk->stack); + rt_mutex_debug_task_free(tsk); + ftrace_graph_exit_task(tsk); ++ if (task_utrace_struct(tsk)) ++ utrace_free_task(tsk); + free_task_struct(tsk); + } + EXPORT_SYMBOL(free_task); +@@ -1092,6 +1095,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, + if (!p) + goto fork_out; + ++ utrace_init_task(p); ++ + ftrace_graph_init_task(p); + + rt_mutex_init_task(p); +@@ -1527,6 +1532,8 @@ long do_fork(unsigned long clone_flags, + init_completion(&vfork); + } + ++ UTRACE_HOOK(current, CLONE, report_clone(clone_flags, p)); ++ + /* + * We set PF_STARTING at creation in case tracing wants to + * use this to distinguish a fully live task from one that +@@ -1538,6 +1545,8 @@ long do_fork(unsigned long clone_flags, + wake_up_new_task(p); + + /* forking complete and child started to run, tell ptracer */ ++ if (clone_flags & CLONE_VFORK) ++ UTRACE_HOOK(current, CLONE, finish_vfork(current)); + if (unlikely(trace)) + ptrace_event(trace, nr); + +diff --git a/kernel/ptrace.c b/kernel/ptrace.c +index 00ab2ca..a7024b8 100644 +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -24,7 +24,34 @@ + #include <linux/regset.h> + #include <linux/hw_breakpoint.h> + #include <linux/cn_proc.h> ++#include <linux/utrace.h> + ++void ptrace_signal_wake_up(struct task_struct *p, int quiescent) ++{ ++ unsigned int state; ++ ++ set_tsk_thread_flag(p, TIF_SIGPENDING); ++ ++ state = TASK_INTERRUPTIBLE; ++ if (quiescent) ++ state |= (__TASK_STOPPED | __TASK_TRACED); ++ if (!wake_up_quiescent(p, state)) ++ kick_process(p); ++} ++ ++static void ptrace_set_syscall_trace(struct task_struct *p, bool on) ++{ ++ task_utrace_lock(p); ++ if (on) { ++ p->ptrace |= PT_SYSCALL_TRACE; ++ set_tsk_thread_flag(p, TIF_SYSCALL_TRACE); ++ } else { ++ p->ptrace &= ~PT_SYSCALL_TRACE; ++ if (!(task_utrace_flags(p) & UTRACE_EVENT_SYSCALL)) ++ clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); ++ } ++ task_utrace_unlock(p); ++} + + static int ptrace_trapping_sleep_fn(void *flags) + { +@@ -117,7 +144,7 @@ void __ptrace_unlink(struct task_struct *child) + * TASK_KILLABLE sleeps. + */ + if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child)) +- signal_wake_up(child, task_is_traced(child)); ++ ptrace_signal_wake_up(child, task_is_traced(child)); + + spin_unlock(&child->sighand->siglock); + } +@@ -315,7 +342,7 @@ static int ptrace_attach(struct task_struct *task, long request, + */ + if (task_is_stopped(task) && + task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING)) +- signal_wake_up(task, 1); ++ ptrace_signal_wake_up(task, 1); + + spin_unlock(&task->sighand->siglock); + +@@ -425,7 +452,7 @@ static int ptrace_detach(struct task_struct *child, unsigned int data) + + /* Architecture-specific hardware disable .. */ + ptrace_disable(child); +- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); ++ ptrace_set_syscall_trace(child, false); + + write_lock_irq(&tasklist_lock); + /* +@@ -608,13 +635,12 @@ static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) + static int ptrace_resume(struct task_struct *child, long request, + unsigned long data) + { ++ unsigned long flags; ++ + if (!valid_signal(data)) + return -EIO; + +- if (request == PTRACE_SYSCALL) +- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); +- else +- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); ++ ptrace_set_syscall_trace(child, request == PTRACE_SYSCALL); + + #ifdef TIF_SYSCALL_EMU + if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP) +@@ -623,20 +649,23 @@ static int ptrace_resume(struct task_struct *child, long request, + clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); + #endif + ++ child->ptrace &= ~(PT_SINGLE_STEP | PT_SINGLE_BLOCK); + if (is_singleblock(request)) { + if (unlikely(!arch_has_block_step())) + return -EIO; +- user_enable_block_step(child); ++ child->ptrace |= PT_SINGLE_BLOCK; + } else if (is_singlestep(request) || is_sysemu_singlestep(request)) { + if (unlikely(!arch_has_single_step())) + return -EIO; +- user_enable_single_step(child); +- } else { +- user_disable_single_step(child); ++ child->ptrace |= PT_SINGLE_STEP; + } + + child->exit_code = data; +- wake_up_state(child, __TASK_TRACED); ++ ++ if (lock_task_sighand(child, &flags)) { ++ wake_up_quiescent(child, __TASK_TRACED); ++ unlock_task_sighand(child, &flags); ++ } + + return 0; + } +@@ -744,7 +773,7 @@ int ptrace_request(struct task_struct *child, long request, + * tracee into STOP. + */ + if (likely(task_set_jobctl_pending(child, JOBCTL_TRAP_STOP))) +- signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); ++ ptrace_signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); + + unlock_task_sighand(child, &flags); + ret = 0; +@@ -770,7 +799,7 @@ int ptrace_request(struct task_struct *child, long request, + * start of this trap and now. Trigger re-trap. + */ + if (child->jobctl & JOBCTL_TRAP_NOTIFY) +- signal_wake_up(child, true); ++ ptrace_signal_wake_up(child, true); + ret = 0; + } + unlock_task_sighand(child, &flags); +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index df00cb0..24dfee4 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -1172,7 +1172,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) + * is actually now running somewhere else! + */ + while (task_running(rq, p)) { +- if (match_state && unlikely(p->state != match_state)) ++ if (match_state && !likely(p->state & match_state)) + return 0; + cpu_relax(); + } +diff --git a/kernel/signal.c b/kernel/signal.c +index c73c428..0508d93 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -88,7 +88,7 @@ static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns) + /* + * Tracers may want to know about even ignored signals. + */ +- return !t->ptrace; ++ return !t->ptrace && !UTRACE_FLAG(t, SIGNAL_IGN); + } + + /* +@@ -151,6 +151,11 @@ void recalc_sigpending_and_wake(struct task_struct *t) + + void recalc_sigpending(void) + { ++ if (task_utrace_flags(current) && utrace_interrupt_pending()) { ++ set_thread_flag(TIF_SIGPENDING); ++ return; ++ } ++ + if (!recalc_sigpending_tsk(current) && !freezing(current)) + clear_thread_flag(TIF_SIGPENDING); + +@@ -495,7 +500,7 @@ int unhandled_signal(struct task_struct *tsk, int sig) + if (handler != SIG_IGN && handler != SIG_DFL) + return 0; + /* if ptraced, let the tracer determine */ +- return !tsk->ptrace; ++ return !tracehook_consider_fatal_signal(tsk, sig); + } + + /* +@@ -697,6 +702,29 @@ void signal_wake_up(struct task_struct *t, int resume) + kick_process(t); + } + ++#define STATE_QUIESCENT (__TASK_STOPPED | __TASK_TRACED | __TASK_UTRACED) ++/* ++ * wakes up the STOPPED/TRACED task, must be called with ->siglock held. ++ */ ++int wake_up_quiescent(struct task_struct *p, unsigned int state) ++{ ++ unsigned int quiescent = (p->state & STATE_QUIESCENT); ++ ++ WARN_ON(state & ~(STATE_QUIESCENT | TASK_INTERRUPTIBLE)); ++ ++ if (quiescent) { ++ state &= ~TASK_INTERRUPTIBLE; ++ if ((quiescent & ~state) != 0) { ++ p->state &= ~state; ++ WARN_ON(!(p->state & STATE_QUIESCENT)); ++ WARN_ON(!(p->state & TASK_WAKEKILL)); ++ return 0; ++ } ++ } ++ ++ return wake_up_state(p, state); ++} ++ + /* + * Remove signals in mask from the pending set and queue. + * Returns 1 if any signals were found. +@@ -842,7 +870,7 @@ static void ptrace_trap_notify(struct task_struct *t) + assert_spin_locked(&t->sighand->siglock); + + task_set_jobctl_pending(t, JOBCTL_TRAP_NOTIFY); +- signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); ++ ptrace_signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); + } + + /* +@@ -884,7 +912,7 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) + task_clear_jobctl_pending(t, JOBCTL_STOP_PENDING); + rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); + if (likely(!(t->ptrace & PT_SEIZED))) +- wake_up_state(t, __TASK_STOPPED); ++ wake_up_quiescent(t, __TASK_STOPPED); + else + ptrace_trap_notify(t); + } while_each_thread(p, t); +@@ -983,7 +1011,7 @@ static void complete_signal(int sig, struct task_struct *p, int group) + if (sig_fatal(p, sig) && + !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && + !sigismember(&t->real_blocked, sig) && +- (sig == SIGKILL || !t->ptrace)) { ++ (sig == SIGKILL || !tracehook_consider_fatal_signal(t, sig))) { + /* + * This signal will be fatal to the whole group. + */ +@@ -1913,10 +1941,34 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) + if (gstop_done) + do_notify_parent_cldstop(current, false, why); + +- __set_current_state(TASK_RUNNING); ++ spin_lock_irq(¤t->sighand->siglock); ++ wake_up_quiescent(current, __TASK_TRACED); ++ spin_unlock_irq(¤t->sighand->siglock); ++ + if (clear_code) + current->exit_code = 0; + read_unlock(&tasklist_lock); ++ ++ /* ++ * It is possible that __TASK_UTRACED was added by utrace ++ * while we were __TASK_TRACED and before we take ->siglock ++ * for wake_up_quiescent(), we need to block in this case. ++ * Otherwise this is unnecessary but absolutely harmless. ++ */ ++ schedule(); ++ } ++ ++ utrace_end_stop(); ++ ++ if (current->ptrace & PT_SINGLE_BLOCK) ++ user_enable_block_step(current); ++ else if (current->ptrace & PT_SINGLE_STEP) ++ user_enable_single_step(current); ++ else { ++ user_disable_single_step(current); ++ /* if utrace needs the stepping it should reassert */ ++ if (task_utrace_flags(current)) ++ set_thread_flag(TIF_NOTIFY_RESUME); + } + + /* +@@ -2081,6 +2133,9 @@ static bool do_signal_stop(int signr) + + /* Now we don't run again until woken by SIGCONT or SIGKILL */ + schedule(); ++ ++ utrace_end_stop(); ++ + return true; + } else { + /* +@@ -2231,17 +2286,27 @@ relock: + for (;;) { + struct k_sigaction *ka; + +- if (unlikely(current->jobctl & JOBCTL_STOP_PENDING) && +- do_signal_stop(0)) ++ signr = utrace_hook_signal(current, regs, info, return_ka); ++ if (unlikely(signr < 0)) + goto relock; + +- if (unlikely(current->jobctl & JOBCTL_TRAP_MASK)) { +- do_jobctl_trap(); +- spin_unlock_irq(&sighand->siglock); +- goto relock; +- } ++ if (unlikely(signr != 0)) ++ ka = return_ka; ++ else { ++ if (unlikely(current->jobctl & JOBCTL_STOP_PENDING) && ++ do_signal_stop(0)) ++ goto relock; ++ ++ if (unlikely(current->jobctl & JOBCTL_TRAP_MASK)) { ++ do_jobctl_trap(); ++ spin_unlock_irq(&sighand->siglock); ++ goto relock; ++ } + +- signr = dequeue_signal(current, ¤t->blocked, info); ++ signr = dequeue_signal(current, ¤t->blocked, info); ++ ++ ka = &sighand->action[signr-1]; ++ } + + if (!signr) + break; /* will return 0 */ +@@ -2251,9 +2316,9 @@ relock: + regs, cookie); + if (!signr) + continue; +- } + +- ka = &sighand->action[signr-1]; ++ ka = &sighand->action[signr-1]; ++ } + + /* Trace actually delivered signals. */ + trace_signal_deliver(signr, info, ka); diff --git a/kernel/utrace.c b/kernel/utrace.c new file mode 100644 -index 0000000..ef856c9 +index 0000000..c817a46 --- /dev/null +++ b/kernel/utrace.c -@@ -0,0 +1,2440 @@ +@@ -0,0 +1,2462 @@ +/* + * utrace infrastructure interface for debugging user processes + * @@ -1542,6 +2301,32 @@ index 0000000..ef856c9 +} +module_init(utrace_init); + ++void task_utrace_lock(struct task_struct *task) ++{ ++ struct utrace *utrace = task_utrace_struct(task); ++ ++ if (!utrace) { ++ task_lock(task); ++ utrace = task_utrace_struct(task); ++ if (!utrace) ++ return; ++ ++ task_unlock(task); ++ } ++ ++ spin_lock(&utrace->lock); ++} ++ ++void task_utrace_unlock(struct task_struct *task) ++{ ++ struct utrace *utrace = task_utrace_struct(task); ++ ++ if (utrace) ++ spin_unlock(&utrace->lock); ++ else ++ task_unlock(task); ++} ++ +/* + * Set up @task.utrace for the first time. We can have races + * between two utrace_attach_task() calls here. The task_lock() @@ -1925,6 +2710,8 @@ index 0000000..ef856c9 + */ +#define ENGINE_STOP (1UL << _UTRACE_NEVENTS) + ++#define task_is_utraced(task) ((task->state & __TASK_UTRACED) != 0) ++ +static void mark_engine_wants_stop(struct task_struct *task, + struct utrace_engine *engine) +{ @@ -2039,7 +2826,7 @@ index 0000000..ef856c9 + + ret = 0; + if ((old_flags & ~events) && target != current && -+ !task_is_stopped_or_traced(target) && !target->exit_state) { ++ !task_is_utraced(target) && !target->exit_state) { + /* + * This barrier ensures that our engine->flags changes + * have hit before we examine utrace->reporting, @@ -2086,21 +2873,21 @@ index 0000000..ef856c9 + */ +static bool utrace_do_stop(struct task_struct *target, struct utrace *utrace) +{ -+ if (task_is_stopped(target)) { ++ if (task_is_stopped_or_traced(target)) { + /* + * Stopped is considered quiescent; when it wakes up, it will + * go through utrace_finish_stop() before doing anything else. + */ + spin_lock_irq(&target->sighand->siglock); -+ if (likely(task_is_stopped(target))) -+ __set_task_state(target, TASK_TRACED); ++ if (likely(task_is_stopped_or_traced(target))) ++ target->state |= TASK_UTRACED; + spin_unlock_irq(&target->sighand->siglock); + } else if (utrace->resume > UTRACE_REPORT) { + utrace->resume = UTRACE_REPORT; + set_notify_resume(target); + } + -+ return task_is_traced(target); ++ return task_is_utraced(target); +} + +/* @@ -2111,11 +2898,7 @@ index 0000000..ef856c9 +{ + lockdep_assert_held(&utrace->lock); + spin_lock_irq(&target->sighand->siglock); -+ if (target->signal->flags & SIGNAL_STOP_STOPPED || -+ target->signal->group_stop_count) -+ target->state = TASK_STOPPED; -+ else -+ wake_up_state(target, __TASK_TRACED); ++ wake_up_quiescent(target, __TASK_UTRACED); + spin_unlock_irq(&target->sighand->siglock); +} + @@ -2162,6 +2945,7 @@ index 0000000..ef856c9 + BUG_ON(utrace->death); + flags &= UTRACE_EVENT(REAP); + } else if (!(flags & UTRACE_EVENT_SYSCALL) && ++ !(task->ptrace & PT_SYSCALL_TRACE) && + test_tsk_thread_flag(task, TIF_SYSCALL_TRACE)) { + clear_tsk_thread_flag(task, TIF_SYSCALL_TRACE); + } @@ -2177,7 +2961,7 @@ index 0000000..ef856c9 + /* + * If no more engines want it stopped, wake it up. + */ -+ if (task_is_traced(task) && !(flags & ENGINE_STOP)) { ++ if (task_is_utraced(task) && !(flags & ENGINE_STOP)) { + /* + * It just resumes, so make sure single-step + * is not left set. @@ -2206,7 +2990,7 @@ index 0000000..ef856c9 +void utrace_finish_stop(void) +{ + /* -+ * If we were task_is_traced() and then SIGKILL'ed, make ++ * If we were task_is_utraced() and then SIGKILL'ed, make + * sure we do nothing until the tracer drops utrace->lock. + */ + if (unlikely(__fatal_signal_pending(current))) { @@ -2216,7 +3000,7 @@ index 0000000..ef856c9 +} + +/* -+ * Perform %UTRACE_STOP, i.e. block in TASK_TRACED until woken up. ++ * Perform %UTRACE_STOP, i.e. block in TASK_UTRACED until woken up. + * @task == current, @utrace == current->utrace, which is not locked. + * Return true if we were woken up by SIGKILL even though some utrace + * engine may still want us to stay stopped. @@ -2266,15 +3050,7 @@ index 0000000..ef856c9 + return; + } + -+ __set_current_state(TASK_TRACED); -+ -+ /* -+ * If there is a group stop in progress, -+ * we must participate in the bookkeeping. -+ */ -+ if (unlikely(task->signal->group_stop_count) && -+ !--task->signal->group_stop_count) -+ task->signal->flags = SIGNAL_STOP_STOPPED; ++ __set_current_state(TASK_UTRACED); + + spin_unlock_irq(&task->sighand->siglock); + spin_unlock(&utrace->lock); @@ -2284,14 +3060,14 @@ index 0000000..ef856c9 + utrace_finish_stop(); + + /* -+ * While in TASK_TRACED, we were considered "frozen enough". ++ * While in TASK_UTRACED, we were considered "frozen enough". + * Now that we woke up, it's crucial if we're supposed to be + * frozen that we freeze now before running anything substantial. + */ + try_to_freeze(); + + /* -+ * While we were in TASK_TRACED, complete_signal() considered ++ * While we were in TASK_UTRACED, complete_signal() considered + * us "uninterested" in signal wakeups. Now make sure our + * TIF_SIGPENDING state is correct for normal running. + */ @@ -2562,7 +3338,7 @@ index 0000000..ef856c9 + if (unlikely(IS_ERR(utrace))) + return PTR_ERR(utrace); + -+ reset = task_is_traced(target); ++ reset = task_is_utraced(target); + ret = 0; + + /* @@ -3222,9 +3998,10 @@ index 0000000..ef856c9 + * For this reason, utrace_release_task checks for the event bits that get + * us here, and delays its cleanup for us to do. + */ -+void utrace_report_death(struct task_struct *task, struct utrace *utrace, -+ bool group_dead, int signal) ++void utrace_report_death(struct task_struct *task, bool group_dead, int signal) +{ ++ struct utrace *utrace = task_utrace_struct(task); ++ + INIT_REPORT(report); + + BUG_ON(!task->exit_state); @@ -3274,7 +4051,8 @@ index 0000000..ef856c9 + + case UTRACE_BLOCKSTEP: + if (likely(arch_has_block_step())) { -+ user_enable_block_step(task); ++ if (!ptrace_wants_step(task)) ++ user_enable_block_step(task); + break; + } + @@ -3287,7 +4065,8 @@ index 0000000..ef856c9 + + case UTRACE_SINGLESTEP: + if (likely(arch_has_single_step())) { -+ user_enable_single_step(task); ++ if (!ptrace_wants_step(task)) ++ user_enable_single_step(task); + } else { + /* + * This means some callback is to blame for failing @@ -3302,7 +4081,8 @@ index 0000000..ef856c9 + case UTRACE_REPORT: + case UTRACE_RESUME: + default: -+ user_disable_single_step(task); ++ if (!ptrace_wants_step(task)) ++ user_disable_single_step(task); + break; + } +} @@ -3323,7 +4103,8 @@ index 0000000..ef856c9 + * code path leads to calling into get_signal_to_deliver(), which + * implicitly reenables them by virtue of spin_unlock_irq. + */ -+ local_irq_enable(); ++ if (irqs_disabled()) /* make trace_hardirqs_on() happy */ ++ local_irq_enable(); + + /* + * If this flag is still set it's because there was a signal @@ -3499,7 +4280,7 @@ index 0000000..ef856c9 + ka = NULL; + memset(return_ka, 0, sizeof *return_ka); + } else if (!(task->utrace_flags & UTRACE_EVENT_SIGNAL_ALL) || -+ unlikely(task->signal->group_stop_count)) { ++ unlikely(task->jobctl & JOBCTL_PENDING_MASK)) { + /* + * If no engine is interested in intercepting signals or + * we must stop, let the caller just dequeue them normally @@ -3901,3282 +4682,4 @@ index 0000000..ef856c9 +{ + seq_printf(m, "Utrace:\t%lx\n", p->utrace_flags); +} --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:17 2011 -Return-Path: oleg@redhat.com -Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO - zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:17 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 1CCED128D6B; - Mon, 21 Nov 2011 15:06:17 -0500 (EST) -Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id FWdJDV74o-ay; Mon, 21 Nov 2011 15:06:17 -0500 (EST) -Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 082081285E4; - Mon, 21 Nov 2011 15:06:17 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6E7d015251; - Mon, 21 Nov 2011 15:06:15 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:35 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:33 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 02/33] utrace: add utrace_init_task/utrace_free_task calls -Message-ID: <20111121200133.GA27759@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 -Status: RO -Content-Length: 1295 -Lines: 47 - -Add the necessary copy_process()->utrace_init_task() and -free_task()->utrace_free_task() calls. - -Originally this was the part of "utrace core" patch, but since -tracehooks are dying it doesn't make sense to reintroduce them. -Instead, just call the utrace_ helpers directly. This is fine -even without CONFIG_UTRACE, gcc is smart enough to optimize out -the code in free_task(). - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/fork.c | 5 +++++ - 1 files changed, 5 insertions(+), 0 deletions(-) - -diff --git a/kernel/fork.c b/kernel/fork.c -index ba0d172..b8719c2 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -66,6 +66,7 @@ - #include <linux/user-return-notifier.h> - #include <linux/oom.h> - #include <linux/khugepaged.h> -+#include <linux/utrace.h> - - #include <asm/pgtable.h> - #include <asm/pgalloc.h> -@@ -167,6 +168,8 @@ void free_task(struct task_struct *tsk) - free_thread_info(tsk->stack); - rt_mutex_debug_task_free(tsk); - ftrace_graph_exit_task(tsk); -+ if (task_utrace_struct(tsk)) -+ utrace_free_task(tsk); - free_task_struct(tsk); - } - EXPORT_SYMBOL(free_task); -@@ -1093,6 +1096,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, - if (!p) - goto fork_out; - -+ utrace_init_task(p); -+ - ftrace_graph_init_task(p); - - rt_mutex_init_task(p); --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:20 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:20 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 8779AD87BC; - Mon, 21 Nov 2011 15:06:20 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id umzAMwRd7rMt; Mon, 21 Nov 2011 15:06:20 -0500 (EST) -Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 72C98D8707; - Mon, 21 Nov 2011 15:06:20 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6HAj015261; - Mon, 21 Nov 2011 15:06:18 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:39 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:36 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 03/33] tracehooks: add utrace hooks -Message-ID: <20111121200136.GA27766@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 -Status: RO -Content-Length: 2310 -Lines: 75 - -Add the necessary utrace hooks in the tracehooks which were not -removed yet. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/tracehook.h | 22 +++++++++++++++++++++- - 1 files changed, 21 insertions(+), 1 deletions(-) - -diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h -index a71a292..8cc28bc 100644 ---- a/include/linux/tracehook.h -+++ b/include/linux/tracehook.h -@@ -49,6 +49,7 @@ - #include <linux/sched.h> - #include <linux/ptrace.h> - #include <linux/security.h> -+#include <linux/utrace.h> - struct linux_binprm; - - /* -@@ -96,6 +97,9 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) - static inline __must_check int tracehook_report_syscall_entry( - struct pt_regs *regs) - { -+ if ((task_utrace_flags(current) & UTRACE_EVENT(SYSCALL_ENTRY)) && -+ utrace_report_syscall_entry(regs)) -+ return 1; - ptrace_report_syscall(regs); - return 0; - } -@@ -119,6 +123,9 @@ static inline __must_check int tracehook_report_syscall_entry( - */ - static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) - { -+ if (task_utrace_flags(current) & UTRACE_EVENT(SYSCALL_EXIT)) -+ utrace_report_syscall_exit(regs); -+ - if (step) { - siginfo_t info; - user_single_step_siginfo(current, regs, &info); -@@ -148,6 +155,8 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, - const struct k_sigaction *ka, - struct pt_regs *regs, int stepping) - { -+ if (task_utrace_flags(current)) -+ utrace_signal_handler(current, stepping); - if (stepping) - ptrace_notify(SIGTRAP); - } -@@ -179,10 +188,21 @@ static inline void set_notify_resume(struct task_struct *task) - * asynchronously, this will be called again before we return to - * user mode. - * -- * Called without locks. -+ * Called without locks. However, on some machines this may be -+ * called with interrupts disabled. - */ - static inline void tracehook_notify_resume(struct pt_regs *regs) - { -+ struct task_struct *task = current; -+ /* -+ * Prevent the following store/load from getting ahead of the -+ * caller which clears TIF_NOTIFY_RESUME. This pairs with the -+ * implicit mb() before setting TIF_NOTIFY_RESUME in -+ * set_notify_resume(). -+ */ -+ smp_mb(); -+ if (task_utrace_flags(task)) -+ utrace_resume(task, regs); - } - #endif /* TIF_NOTIFY_RESUME */ - --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:23 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:23 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 6559BD4FDE; - Mon, 21 Nov 2011 15:06:23 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 6BjISiO+cS1U; Mon, 21 Nov 2011 15:06:23 -0500 (EST) -Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 50366D4C39; - Mon, 21 Nov 2011 15:06:23 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6KT9017533; - Mon, 21 Nov 2011 15:06:21 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:42 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:39 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 04/33] tracehooks: reintroduce - tracehook_consider_fatal_signal() -Message-ID: <20111121200139.GA27769@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 -Status: RO -Content-Length: 3257 -Lines: 90 - -Add the killed tracehook_consider_fatal_signal() back. It has multiple -callers and it is not easy add the necessary checks inline. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - arch/s390/kernel/traps.c | 4 ++-- - include/linux/tracehook.h | 22 ++++++++++++++++++++++ - kernel/signal.c | 4 ++-- - 3 files changed, 26 insertions(+), 4 deletions(-) - -diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c -index a9807dd..f506e1b 100644 ---- a/arch/s390/kernel/traps.c -+++ b/arch/s390/kernel/traps.c -@@ -329,7 +329,7 @@ void __kprobes do_per_trap(struct pt_regs *regs) - - if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP) - return; -- if (!current->ptrace) -+ if (!tracehook_consider_fatal_signal(current, SIGTRAP)) - return; - info.si_signo = SIGTRAP; - info.si_errno = 0; -@@ -429,7 +429,7 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code, - if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) - return; - if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { -- if (current->ptrace) { -+ if (tracehook_consider_fatal_signal(current, SIGTRAP)) { - info.si_signo = SIGTRAP; - info.si_errno = 0; - info.si_code = TRAP_BRKPT; -diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h -index 8cc28bc..ec2af67 100644 ---- a/include/linux/tracehook.h -+++ b/include/linux/tracehook.h -@@ -161,6 +161,28 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, - ptrace_notify(SIGTRAP); - } - -+/** -+ * tracehook_consider_fatal_signal - suppress special handling of fatal signal -+ * @task: task receiving the signal -+ * @sig: signal number being sent -+ * -+ * Return nonzero to prevent special handling of this termination signal. -+ * Normally handler for signal is %SIG_DFL. It can be %SIG_IGN if @sig is -+ * ignored, in which case force_sig() is about to reset it to %SIG_DFL. -+ * When this returns zero, this signal might cause a quick termination -+ * that does not give the debugger a chance to intercept the signal. -+ * -+ * Called with or without @task->sighand->siglock held. -+ */ -+static inline int tracehook_consider_fatal_signal(struct task_struct *task, -+ int sig) -+{ -+ if (unlikely(task_utrace_flags(task) & (UTRACE_EVENT(SIGNAL_TERM) | -+ UTRACE_EVENT(SIGNAL_CORE)))) -+ return 1; -+ return task->ptrace != 0; -+} -+ - #ifdef TIF_NOTIFY_RESUME - /** - * set_notify_resume - cause tracehook_notify_resume() to be called -diff --git a/kernel/signal.c b/kernel/signal.c -index b3f78d0..d7b90cd 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -494,7 +494,7 @@ int unhandled_signal(struct task_struct *tsk, int sig) - if (handler != SIG_IGN && handler != SIG_DFL) - return 0; - /* if ptraced, let the tracer determine */ -- return !tsk->ptrace; -+ return !tracehook_consider_fatal_signal(tsk, sig); - } - - /* -@@ -982,7 +982,7 @@ static void complete_signal(int sig, struct task_struct *p, int group) - if (sig_fatal(p, sig) && - !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && - !sigismember(&t->real_blocked, sig) && -- (sig == SIGKILL || !t->ptrace)) { -+ (sig == SIGKILL || !tracehook_consider_fatal_signal(t, sig))) { - /* - * This signal will be fatal to the whole group. - */ --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:26 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:25 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id E7A2DD498A; - Mon, 21 Nov 2011 15:06:25 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 4L9zskFVsr4I; Mon, 21 Nov 2011 15:06:25 -0500 (EST) -Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id D3487D4C39; - Mon, 21 Nov 2011 15:06:25 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6Nnp017552; - Mon, 21 Nov 2011 15:06:24 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:44 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:42 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 05/33] add utrace hooks into sig_ignored() and - recalc_sigpending() -Message-ID: <20111121200142.GA27777@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 -Status: RO -Content-Length: 1508 -Lines: 51 - -Add the necessary and somewhat "special" hooks into sig_ignored() and -recalc_sigpending(). Basically this restores _force_sigpending() and -_consider_ignored_signal() tracehook logic. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/utrace.h | 2 ++ - kernel/signal.c | 7 ++++++- - 2 files changed, 8 insertions(+), 1 deletions(-) - -diff --git a/include/linux/utrace.h b/include/linux/utrace.h -index f251efe..1b8da1c 100644 ---- a/include/linux/utrace.h -+++ b/include/linux/utrace.h -@@ -107,6 +107,8 @@ bool utrace_report_syscall_entry(struct pt_regs *); - void utrace_report_syscall_exit(struct pt_regs *); - void utrace_signal_handler(struct task_struct *, int); - -+#define UTRACE_FLAG(task, ev) (task_utrace_flags(task) & UTRACE_EVENT(ev)) -+ - #ifndef CONFIG_UTRACE - - /* -diff --git a/kernel/signal.c b/kernel/signal.c -index d7b90cd..8594cb2 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -87,7 +87,7 @@ static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns) - /* - * Tracers may want to know about even ignored signals. - */ -- return !t->ptrace; -+ return !t->ptrace && !UTRACE_FLAG(t, SIGNAL_IGN); - } - - /* -@@ -150,6 +150,11 @@ void recalc_sigpending_and_wake(struct task_struct *t) - - void recalc_sigpending(void) - { -+ if (task_utrace_flags(current) && utrace_interrupt_pending()) { -+ set_thread_flag(TIF_SIGPENDING); -+ return; -+ } -+ - if (!recalc_sigpending_tsk(current) && !freezing(current)) - clear_thread_flag(TIF_SIGPENDING); - --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:28 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:28 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 6E4A6D4F4A; - Mon, 21 Nov 2011 15:06:28 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id vEeGLyK1+rX9; Mon, 21 Nov 2011 15:06:28 -0500 (EST) -Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 5AD50D4C39; - Mon, 21 Nov 2011 15:06:28 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK6QOB029543; - Mon, 21 Nov 2011 15:06:26 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:47 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:45 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 06/33] restore the EXEC/EXIT/CLONE utrace hooks -Message-ID: <20111121200145.GA27780@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 -Status: RO -Content-Length: 2383 -Lines: 83 - -Restore the "trivial" EXEC/EXIT/CLONE utrace hooks. Add the -simple helper, UTRACE_HOOK(), to minimize the changes. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - fs/exec.c | 5 ++++- - include/linux/utrace.h | 6 ++++++ - kernel/exit.c | 1 + - kernel/fork.c | 4 ++++ - 4 files changed, 15 insertions(+), 1 deletions(-) - -diff --git a/fs/exec.c b/fs/exec.c -index 3625464..7d8f8bd 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1397,9 +1397,12 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) - */ - bprm->recursion_depth = depth; - if (retval >= 0) { -- if (depth == 0) -+ if (depth == 0) { -+ UTRACE_HOOK(current, EXEC, -+ report_exec(fmt, bprm, regs)); - ptrace_event(PTRACE_EVENT_EXEC, - old_pid); -+ } - put_binfmt(fmt); - allow_write_access(bprm->file); - if (bprm->file) -diff --git a/include/linux/utrace.h b/include/linux/utrace.h -index 1b8da1c..9ac0b1b 100644 ---- a/include/linux/utrace.h -+++ b/include/linux/utrace.h -@@ -109,6 +109,12 @@ void utrace_signal_handler(struct task_struct *, int); - - #define UTRACE_FLAG(task, ev) (task_utrace_flags(task) & UTRACE_EVENT(ev)) - -+#define UTRACE_HOOK(task, ev, callback) \ -+ do { \ -+ if (UTRACE_FLAG(task, ev)) \ -+ utrace_ ## callback; \ -+ } while (0) -+ - #ifndef CONFIG_UTRACE - - /* -diff --git a/kernel/exit.c b/kernel/exit.c -index d0b7d98..f5eba3b 100644 ---- a/kernel/exit.c -+++ b/kernel/exit.c -@@ -911,6 +911,7 @@ NORET_TYPE void do_exit(long code) - */ - set_fs(USER_DS); - -+ UTRACE_HOOK(current, EXIT, report_exit(&code)); - ptrace_event(PTRACE_EVENT_EXIT, code); - - validate_creds_for_do_exit(tsk); -diff --git a/kernel/fork.c b/kernel/fork.c -index b8719c2..09d5049 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -1535,6 +1535,8 @@ long do_fork(unsigned long clone_flags, - - audit_finish_fork(p); - -+ UTRACE_HOOK(current, CLONE, report_clone(clone_flags, p)); -+ - /* - * We set PF_STARTING at creation in case tracing wants to - * use this to distinguish a fully live task from one that -@@ -1546,6 +1548,8 @@ long do_fork(unsigned long clone_flags, - wake_up_new_task(p); - - /* forking complete and child started to run, tell ptracer */ -+ if (clone_flags & CLONE_VFORK) -+ UTRACE_HOOK(current, CLONE, finish_vfork(current)); - if (unlikely(trace)) - ptrace_event(trace, nr); - --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:30 2011 -Return-Path: oleg@redhat.com -Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO - zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:30 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id D248D1284E0; - Mon, 21 Nov 2011 15:06:30 -0500 (EST) -Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id divvekTmLScS; Mon, 21 Nov 2011 15:06:30 -0500 (EST) -Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id BDC9412800E; - Mon, 21 Nov 2011 15:06:30 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK6Shj029546; - Mon, 21 Nov 2011 15:06:29 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:49 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:47 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 07/33] utrace: utrace_report_death() can use - task_utrace_struct() -Message-ID: <20111121200147.GA27787@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 -Status: RO -Content-Length: 1692 -Lines: 44 - -utrace_report_death() assumes that the caller (exit_notify) should -pass task->utrace as an argument. This is no longer needed, it can -safely do task_utrace_struct(). This way we avoid the nasty changes -in exit_notify(). - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/utrace.h | 2 +- - kernel/utrace.c | 5 +++-- - 2 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/include/linux/utrace.h b/include/linux/utrace.h -index 9ac0b1b..9a2e2f4 100644 ---- a/include/linux/utrace.h -+++ b/include/linux/utrace.h -@@ -99,7 +99,7 @@ int utrace_get_signal(struct task_struct *, struct pt_regs *, - void utrace_report_clone(unsigned long, struct task_struct *); - void utrace_finish_vfork(struct task_struct *); - void utrace_report_exit(long *exit_code); --void utrace_report_death(struct task_struct *, struct utrace *, bool, int); -+void utrace_report_death(struct task_struct *, bool, int); - void utrace_report_jctl(int notify, int type); - void utrace_report_exec(struct linux_binfmt *, struct linux_binprm *, - struct pt_regs *regs); -diff --git a/kernel/utrace.c b/kernel/utrace.c -index ef856c9..1e750ad 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -1759,9 +1759,10 @@ void utrace_report_exit(long *exit_code) - * For this reason, utrace_release_task checks for the event bits that get - * us here, and delays its cleanup for us to do. - */ --void utrace_report_death(struct task_struct *task, struct utrace *utrace, -- bool group_dead, int signal) -+void utrace_report_death(struct task_struct *task, bool group_dead, int signal) - { -+ struct utrace *utrace = task_utrace_struct(task); -+ - INIT_REPORT(report); - - BUG_ON(!task->exit_state); --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:33 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:33 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 62E1BD50A3; - Mon, 21 Nov 2011 15:06:33 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id FB36YkOAHDc5; Mon, 21 Nov 2011 15:06:33 -0500 (EST) -Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 4D161D4C39; - Mon, 21 Nov 2011 15:06:33 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6VBW022130; - Mon, 21 Nov 2011 15:06:31 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:52 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:50 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 08/33] restore the DEATH/REAP utrace hooks -Message-ID: <20111121200150.GA27790@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 -Status: RO -Content-Length: 2346 -Lines: 70 - -Restore the necessary hooks in release_task() and exit_notify(), -add the corresponding helpers into utrace.h. - -Note: the @signal argument passed to ->report_death() does not -match the previous behaviour. I think this shouldn't affect the -current users, and I bet nobody can really understand what this -magic argument should actually mean anyway. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/utrace.h | 22 ++++++++++++++++++++++ - kernel/exit.c | 4 ++++ - 2 files changed, 26 insertions(+), 0 deletions(-) - -diff --git a/include/linux/utrace.h b/include/linux/utrace.h -index 9a2e2f4..cf13839 100644 ---- a/include/linux/utrace.h -+++ b/include/linux/utrace.h -@@ -697,4 +697,26 @@ static inline __must_check int utrace_barrier_pid(struct pid *pid, - - #endif /* CONFIG_UTRACE */ - -+static inline void utrace_release_task(struct task_struct *task) -+{ -+ /* see utrace_add_engine() about this barrier */ -+ smp_mb(); -+ if (task_utrace_flags(task)) -+ utrace_maybe_reap(task, task_utrace_struct(task), true); -+} -+ -+static inline void utrace_exit_notify(struct task_struct *task, -+ int signal, int group_dead) -+{ -+ /* -+ * If utrace_set_events() was just called to enable -+ * UTRACE_EVENT(DEATH), then we are obliged to call -+ * utrace_report_death() and not miss it. utrace_set_events() -+ * checks @task->exit_state under tasklist_lock to synchronize -+ * with exit_notify(), the caller. -+ */ -+ if (task_utrace_flags(task) & _UTRACE_DEATH_EVENTS) -+ utrace_report_death(task, group_dead, signal); -+} -+ - #endif /* linux/utrace.h */ -diff --git a/kernel/exit.c b/kernel/exit.c -index f5eba3b..746c5df 100644 ---- a/kernel/exit.c -+++ b/kernel/exit.c -@@ -168,6 +168,8 @@ void release_task(struct task_struct * p) - struct task_struct *leader; - int zap_leader; - repeat: -+ utrace_release_task(p); -+ - /* don't need to get the RCU readlock here - the process is dead and - * can't be modifying its own credentials. But shut RCU-lockdep up */ - rcu_read_lock(); -@@ -858,6 +860,8 @@ static void exit_notify(struct task_struct *tsk, int group_dead) - wake_up_process(tsk->signal->group_exit_task); - write_unlock_irq(&tasklist_lock); - -+ utrace_exit_notify(tsk, autoreap ? -1 : SIGCHLD, group_dead); -+ - /* If the process is dead, release it - nobody will wait for it */ - if (autoreap) - release_task(tsk); --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:35 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:35 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id D4AB3D8761; - Mon, 21 Nov 2011 15:06:35 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id TiShkH1f6rnj; Mon, 21 Nov 2011 15:06:35 -0500 (EST) -Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id BCB85D877F; - Mon, 21 Nov 2011 15:06:35 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6XNu015312; - Mon, 21 Nov 2011 15:06:34 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:54 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:52 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 09/33] utrace: remove jobctl bits -Message-ID: <20111121200152.GA27793@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 -Status: RO -Content-Length: 1888 -Lines: 56 - -- change utrace_get_signal() to check JOBCTL_STOP_PENDING instead of - signal->group_stop_count. With the recent changes group_stop_count - doesn't necessarily mean this task should participate in group stop. - -- remove the "participate in group stop" code from utrace_wakeup() and - utrace_stop(), this is no longer needed and wrong. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/utrace.c | 16 ++-------------- - 1 files changed, 2 insertions(+), 14 deletions(-) - -diff --git a/kernel/utrace.c b/kernel/utrace.c -index 1e750ad..5d3974e 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -648,11 +648,7 @@ static void utrace_wakeup(struct task_struct *target, struct utrace *utrace) - { - lockdep_assert_held(&utrace->lock); - spin_lock_irq(&target->sighand->siglock); -- if (target->signal->flags & SIGNAL_STOP_STOPPED || -- target->signal->group_stop_count) -- target->state = TASK_STOPPED; -- else -- wake_up_state(target, __TASK_TRACED); -+ wake_up_state(target, __TASK_TRACED); - spin_unlock_irq(&target->sighand->siglock); - } - -@@ -805,14 +801,6 @@ relock: - - __set_current_state(TASK_TRACED); - -- /* -- * If there is a group stop in progress, -- * we must participate in the bookkeeping. -- */ -- if (unlikely(task->signal->group_stop_count) && -- !--task->signal->group_stop_count) -- task->signal->flags = SIGNAL_STOP_STOPPED; -- - spin_unlock_irq(&task->sighand->siglock); - spin_unlock(&utrace->lock); - -@@ -2037,7 +2025,7 @@ int utrace_get_signal(struct task_struct *task, struct pt_regs *regs, - ka = NULL; - memset(return_ka, 0, sizeof *return_ka); - } else if (!(task->utrace_flags & UTRACE_EVENT_SIGNAL_ALL) || -- unlikely(task->signal->group_stop_count)) { -+ unlikely(task->jobctl & JOBCTL_STOP_PENDING)) { - /* - * If no engine is interested in intercepting signals or - * we must stop, let the caller just dequeue them normally --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:38 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:38 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 425CED8707; - Mon, 21 Nov 2011 15:06:38 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 9paRC+dwSflh; Mon, 21 Nov 2011 15:06:38 -0500 (EST) -Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 2DDBCD8410; - Mon, 21 Nov 2011 15:06:38 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK6a31031355; - Mon, 21 Nov 2011 15:06:36 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:56 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:55 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 10/33] ptrace: take ->siglock around s/TRACED/RUNNING/ -Message-ID: <20111121200155.GA27801@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 -Status: RO -Content-Length: 1624 -Lines: 56 - -change ptrace_resume() and ptrace_stop() to take ->siglock around changing -task->state from TRACED to RUNNING. - -With this patch __TASK_TRACED/STOPPED bits are fully protected by ->siglock, -nobody can set or clear these bits without ->siglock held. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/ptrace.c | 8 +++++++- - kernel/signal.c | 3 +++ - 2 files changed, 10 insertions(+), 1 deletions(-) - -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index 24d0447..daf47bc 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -589,6 +589,8 @@ static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) - static int ptrace_resume(struct task_struct *child, long request, - unsigned long data) - { -+ unsigned long flags; -+ - if (!valid_signal(data)) - return -EIO; - -@@ -617,7 +619,11 @@ static int ptrace_resume(struct task_struct *child, long request, - } - - child->exit_code = data; -- wake_up_state(child, __TASK_TRACED); -+ -+ if (lock_task_sighand(child, &flags)) { -+ wake_up_state(child, __TASK_TRACED); -+ unlock_task_sighand(child, &flags); -+ } - - return 0; - } -diff --git a/kernel/signal.c b/kernel/signal.c -index 8594cb2..4512bb4 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -1886,7 +1886,10 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) - if (gstop_done) - do_notify_parent_cldstop(current, false, why); - -+ spin_lock_irq(¤t->sighand->siglock); - __set_current_state(TASK_RUNNING); -+ spin_unlock_irq(¤t->sighand->siglock); -+ - if (clear_code) - current->exit_code = 0; - read_unlock(&tasklist_lock); --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:40 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:40 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B0D19D877F; - Mon, 21 Nov 2011 15:06:40 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 3jv-cDBpMP5B; Mon, 21 Nov 2011 15:06:40 -0500 (EST) -Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 9C98DD8410; - Mon, 21 Nov 2011 15:06:40 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK6cHF029573; - Mon, 21 Nov 2011 15:06:39 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:01:59 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:57 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 11/33] introduce wake_up_quiescent() -Message-ID: <20111121200157.GA27805@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 -Status: RO -Content-Length: 3186 -Lines: 93 - -No functional changes. Add the new helper, wake_up_quiescent(task, state), -which simply returns wake_up_state(task, state). Change all callers which -do wake_up_state(STOPPED/TRACED) to use the new helper. ptrace_stop() is -a bit special, it does __set_current_state(RUNNING) in the very unlikely -case, change it as well. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/signal.h | 2 ++ - kernel/ptrace.c | 2 +- - kernel/signal.c | 12 ++++++++++-- - kernel/utrace.c | 2 +- - 4 files changed, 14 insertions(+), 4 deletions(-) - -diff --git a/include/linux/signal.h b/include/linux/signal.h -index a822300..2be3712 100644 ---- a/include/linux/signal.h -+++ b/include/linux/signal.h -@@ -239,6 +239,8 @@ static inline int valid_signal(unsigned long sig) - struct timespec; - struct pt_regs; - -+extern int wake_up_quiescent(struct task_struct *p, unsigned int state); -+ - extern int next_signal(struct sigpending *pending, sigset_t *mask); - extern int do_send_sig_info(int sig, struct siginfo *info, - struct task_struct *p, bool group); -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index daf47bc..8439ef1 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -621,7 +621,7 @@ static int ptrace_resume(struct task_struct *child, long request, - child->exit_code = data; - - if (lock_task_sighand(child, &flags)) { -- wake_up_state(child, __TASK_TRACED); -+ wake_up_quiescent(child, __TASK_TRACED); - unlock_task_sighand(child, &flags); - } - -diff --git a/kernel/signal.c b/kernel/signal.c -index 4512bb4..99a6008 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -702,6 +702,14 @@ void signal_wake_up(struct task_struct *t, int resume) - } - - /* -+ * wakes up the STOPPED/TRACED task, must be called with ->siglock held. -+ */ -+int wake_up_quiescent(struct task_struct *p, unsigned int state) -+{ -+ return wake_up_state(p, state); -+} -+ -+/* - * Remove signals in mask from the pending set and queue. - * Returns 1 if any signals were found. - * -@@ -888,7 +896,7 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) - task_clear_jobctl_pending(t, JOBCTL_STOP_PENDING); - rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); - if (likely(!(t->ptrace & PT_SEIZED))) -- wake_up_state(t, __TASK_STOPPED); -+ wake_up_quiescent(t, __TASK_STOPPED); - else - ptrace_trap_notify(t); - } while_each_thread(p, t); -@@ -1887,7 +1895,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) - do_notify_parent_cldstop(current, false, why); - - spin_lock_irq(¤t->sighand->siglock); -- __set_current_state(TASK_RUNNING); -+ wake_up_quiescent(current, __TASK_TRACED); - spin_unlock_irq(¤t->sighand->siglock); - - if (clear_code) -diff --git a/kernel/utrace.c b/kernel/utrace.c -index 5d3974e..cebc390 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -648,7 +648,7 @@ static void utrace_wakeup(struct task_struct *target, struct utrace *utrace) - { - lockdep_assert_held(&utrace->lock); - spin_lock_irq(&target->sighand->siglock); -- wake_up_state(target, __TASK_TRACED); -+ wake_up_quiescent(target, __TASK_TRACED); - spin_unlock_irq(&target->sighand->siglock); - } - --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:43 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:43 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 6488BD514C; - Mon, 21 Nov 2011 15:06:43 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id TKQUj5mU4NYM; Mon, 21 Nov 2011 15:06:43 -0500 (EST) -Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 4EC82D5000; - Mon, 21 Nov 2011 15:06:43 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6fp6015343; - Mon, 21 Nov 2011 15:06:41 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:02 +0100 (CET) -Date: Mon, 21 Nov 2011 21:01:59 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 12/33] introduce ptrace_signal_wake_up() -Message-ID: <20111121200159.GA27812@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 -Status: RO -Content-Length: 3670 -Lines: 113 - -Add the new helper, ptrace_signal_wake_up(), change ptrace.c/signal.c -to use it instead of signal_wake_up() to wake up a STOPPED/TRACED task. - -The new helper does almost the same, except: - - - it doesn't use the TASK_WAKEKILL bit to wake up the TRACED - or STOPPED task, it uses __TASK_STOPPED | __TASK_TRACED - explicitly. This is what ptrace actually wants, it should - never wake up a TASK_KILLABLE task. - - This should be cleanuped upatream, signal_wake_up() should - take the state as an argument, not a boolean. Until then - we add a new static helper. - - - it uses wake_up_quiescent() instead of wake_up_state(). - -Thereafter every change from STOPPED/TRACED to RUNNING is done via -wake_up_quiescent(). - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/ptrace.h | 1 + - kernel/ptrace.c | 20 ++++++++++++++++---- - kernel/signal.c | 2 +- - 3 files changed, 18 insertions(+), 5 deletions(-) - -diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h -index 800f113..6d9282a 100644 ---- a/include/linux/ptrace.h -+++ b/include/linux/ptrace.h -@@ -113,6 +113,7 @@ - #include <linux/compiler.h> /* For unlikely. */ - #include <linux/sched.h> /* For struct task_struct. */ - -+extern void ptrace_signal_wake_up(struct task_struct *p, int quiescent); - - extern long arch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data); -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index 8439ef1..a464ab5 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -25,6 +25,18 @@ - #include <linux/hw_breakpoint.h> - #include <linux/cn_proc.h> - -+void ptrace_signal_wake_up(struct task_struct *p, int quiescent) -+{ -+ unsigned int state; -+ -+ set_tsk_thread_flag(p, TIF_SIGPENDING); -+ -+ state = TASK_INTERRUPTIBLE; -+ if (quiescent) -+ state |= (__TASK_STOPPED | __TASK_TRACED); -+ if (!wake_up_quiescent(p, state)) -+ kick_process(p); -+} - - static int ptrace_trapping_sleep_fn(void *flags) - { -@@ -106,7 +118,7 @@ void __ptrace_unlink(struct task_struct *child) - * TASK_KILLABLE sleeps. - */ - if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child)) -- signal_wake_up(child, task_is_traced(child)); -+ ptrace_signal_wake_up(child, task_is_traced(child)); - - spin_unlock(&child->sighand->siglock); - } -@@ -296,7 +308,7 @@ static int ptrace_attach(struct task_struct *task, long request, - */ - if (task_is_stopped(task) && - task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING)) -- signal_wake_up(task, 1); -+ ptrace_signal_wake_up(task, 1); - - spin_unlock(&task->sighand->siglock); - -@@ -731,7 +743,7 @@ int ptrace_request(struct task_struct *child, long request, - * tracee into STOP. - */ - if (likely(task_set_jobctl_pending(child, JOBCTL_TRAP_STOP))) -- signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); -+ ptrace_signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); - - unlock_task_sighand(child, &flags); - ret = 0; -@@ -757,7 +769,7 @@ int ptrace_request(struct task_struct *child, long request, - * start of this trap and now. Trigger re-trap. - */ - if (child->jobctl & JOBCTL_TRAP_NOTIFY) -- signal_wake_up(child, true); -+ ptrace_signal_wake_up(child, true); - ret = 0; - } - unlock_task_sighand(child, &flags); -diff --git a/kernel/signal.c b/kernel/signal.c -index 99a6008..7a47a93 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -854,7 +854,7 @@ static void ptrace_trap_notify(struct task_struct *t) - assert_spin_locked(&t->sighand->siglock); - - task_set_jobctl_pending(t, JOBCTL_TRAP_NOTIFY); -- signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); -+ ptrace_signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); - } - - /* --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:46 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:46 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 3A7AED8410; - Mon, 21 Nov 2011 15:06:46 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id jhYAwDyYmdhg; Mon, 21 Nov 2011 15:06:46 -0500 (EST) -Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 25D5FD889A; - Mon, 21 Nov 2011 15:06:46 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK6h29029619; - Mon, 21 Nov 2011 15:06:44 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:04 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:02 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 13/33] wait_task_inactive: treat task->state and - match_state as bitmasks -Message-ID: <20111121200202.GA27816@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 -Status: RO -Content-Length: 1558 -Lines: 39 - -Change wait_task_inactive() to check "state & match_state" instead of -"state == match_state". This should not make any difference, but this -allows us to add more "stopped" bits which can be set or cleared -independently. - -IOW. wait_task_inactive() assumes that if task->state != 0, it can -only be changed to TASK_RUNNING. Currently this is true, and in this -case "state & match_state" continues to work. But, unlike the current -check, it also works if task->state has other bits set while the caller -is only interested in, say, __TASK_TRACED. - -Note: I think wait_task_inactive() should be cleanuped upstrean anyway, -nowadays we have TASK_WAKING and task->state != 0 doesn't necessarily -mean it is TASK_RUNNING. It also makes sense to exclude the !TASK_REPORT -bits during the check. Finally, probably this patch makes sense anyway -even without utrace. For example, a stopped _and_ traced thread could -have task->state = TASK_STOPPED | TASK_TRACED, this can be useful. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/sched.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/kernel/sched.c b/kernel/sched.c -index 0e9344a..84ecc0a 100644 ---- a/kernel/sched.c -+++ b/kernel/sched.c -@@ -2443,7 +2443,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) - * is actually now running somewhere else! - */ - while (task_running(rq, p)) { -- if (match_state && unlikely(p->state != match_state)) -+ if (match_state && !likely(p->state & match_state)) - return 0; - cpu_relax(); - } --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:48 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:48 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id C2934D5000; - Mon, 21 Nov 2011 15:06:48 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id ThT2PyhztDpQ; Mon, 21 Nov 2011 15:06:48 -0500 (EST) -Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id ACE02D4F84; - Mon, 21 Nov 2011 15:06:48 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6kdb022201; - Mon, 21 Nov 2011 15:06:47 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:07 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:05 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 14/33] introduce TASK_UTRACED state -Message-ID: <20111121200205.GA27823@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 -Status: RO -Content-Length: 2913 -Lines: 84 - -Introduce TASK_UTRACED state, will be used by utrace instead of TASK_TRACED. - -Note: this state is reported as "t (tracing stop)" to the user-space to -avoid the confusion. IOW, it looks like TASK_TRACED in /proc/pid/status. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - fs/proc/array.c | 11 ++++++----- - include/linux/sched.h | 20 +++++++++++--------- - 2 files changed, 17 insertions(+), 14 deletions(-) - -diff --git a/fs/proc/array.c b/fs/proc/array.c -index f0c0ea2..e0daec4 100644 ---- a/fs/proc/array.c -+++ b/fs/proc/array.c -@@ -138,11 +138,12 @@ static const char * const task_state_array[] = { - "D (disk sleep)", /* 2 */ - "T (stopped)", /* 4 */ - "t (tracing stop)", /* 8 */ -- "Z (zombie)", /* 16 */ -- "X (dead)", /* 32 */ -- "x (dead)", /* 64 */ -- "K (wakekill)", /* 128 */ -- "W (waking)", /* 256 */ -+ "t (tracing stop)", /* 16 (stopped by utrace) */ -+ "Z (zombie)", /* 32 */ -+ "X (dead)", /* 64 */ -+ "x (dead)", /* 128 */ -+ "K (wakekill)", /* 256 */ -+ "W (waking)", /* 512 */ - }; - - static inline const char *get_task_state(struct task_struct *tsk) -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 4d45f93..746b4d3 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -185,16 +185,17 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) - #define TASK_UNINTERRUPTIBLE 2 - #define __TASK_STOPPED 4 - #define __TASK_TRACED 8 -+#define __TASK_UTRACED 16 - /* in tsk->exit_state */ --#define EXIT_ZOMBIE 16 --#define EXIT_DEAD 32 -+#define EXIT_ZOMBIE 32 -+#define EXIT_DEAD 64 - /* in tsk->state again */ --#define TASK_DEAD 64 --#define TASK_WAKEKILL 128 --#define TASK_WAKING 256 --#define TASK_STATE_MAX 512 -+#define TASK_DEAD 128 -+#define TASK_WAKEKILL 256 -+#define TASK_WAKING 512 -+#define TASK_STATE_MAX 1024 - --#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW" -+#define TASK_STATE_TO_CHAR_STR "RSDTtUZXxKW" - - extern char ___assert_task_state[1 - 2*!!( - sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)]; -@@ -203,15 +204,16 @@ extern char ___assert_task_state[1 - 2*!!( - #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) - #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) - #define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED) -+#define TASK_UTRACED (TASK_WAKEKILL | __TASK_UTRACED) - - /* Convenience macros for the sake of wake_up */ - #define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE) --#define TASK_ALL (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED) -+#define TASK_ALL (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED | __TASK_UTRACED) - - /* get_task_state() */ - #define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \ - TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \ -- __TASK_TRACED) -+ __TASK_TRACED | __TASK_UTRACED) - - #define task_is_traced(task) ((task->state & __TASK_TRACED) != 0) - #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0) --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:51 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:51 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 48F35D889C; - Mon, 21 Nov 2011 15:06:51 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id ZXkDvXaDg0cN; Mon, 21 Nov 2011 15:06:51 -0500 (EST) -Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 34485D889A; - Mon, 21 Nov 2011 15:06:51 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6nlT022211; - Mon, 21 Nov 2011 15:06:49 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:09 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:08 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 15/33] utrace: use TASK_UTRACED instead of TASK_TRACED -Message-ID: <20111121200208.GA27826@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 -Status: RO -Content-Length: 4316 -Lines: 130 - -Change utrace.c to use TASK_UTRACED instead of TASK_TRACED. - -- utrace_stop/utrace_wakeup: simply use the new state - -- utrace_do_stop: do not clear STOPPED/TRACED, but add the new - __TASK_UTRACED bit to state the fact that both ptrace and utrace - want this task to be stopped - -- naturally, do not use task_is_traced() to check if this task was - stopped by utrace, use the new task_is_utraced() helper which - checks __TASK_UTRACED. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/utrace.c | 26 ++++++++++++++------------ - 1 files changed, 14 insertions(+), 12 deletions(-) - -diff --git a/kernel/utrace.c b/kernel/utrace.c -index cebc390..2097103 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -462,6 +462,8 @@ static void put_detached_list(struct list_head *list) - */ - #define ENGINE_STOP (1UL << _UTRACE_NEVENTS) - -+#define task_is_utraced(task) ((task->state & __TASK_UTRACED) != 0) -+ - static void mark_engine_wants_stop(struct task_struct *task, - struct utrace_engine *engine) - { -@@ -576,7 +578,7 @@ int utrace_set_events(struct task_struct *target, - - ret = 0; - if ((old_flags & ~events) && target != current && -- !task_is_stopped_or_traced(target) && !target->exit_state) { -+ !task_is_utraced(target) && !target->exit_state) { - /* - * This barrier ensures that our engine->flags changes - * have hit before we examine utrace->reporting, -@@ -623,21 +625,21 @@ static void mark_engine_detached(struct utrace_engine *engine) - */ - static bool utrace_do_stop(struct task_struct *target, struct utrace *utrace) - { -- if (task_is_stopped(target)) { -+ if (task_is_stopped_or_traced(target)) { - /* - * Stopped is considered quiescent; when it wakes up, it will - * go through utrace_finish_stop() before doing anything else. - */ - spin_lock_irq(&target->sighand->siglock); -- if (likely(task_is_stopped(target))) -- __set_task_state(target, TASK_TRACED); -+ if (likely(task_is_stopped_or_traced(target))) -+ target->state |= TASK_UTRACED; - spin_unlock_irq(&target->sighand->siglock); - } else if (utrace->resume > UTRACE_REPORT) { - utrace->resume = UTRACE_REPORT; - set_notify_resume(target); - } - -- return task_is_traced(target); -+ return task_is_utraced(target); - } - - /* -@@ -648,7 +650,7 @@ static void utrace_wakeup(struct task_struct *target, struct utrace *utrace) - { - lockdep_assert_held(&utrace->lock); - spin_lock_irq(&target->sighand->siglock); -- wake_up_quiescent(target, __TASK_TRACED); -+ wake_up_quiescent(target, __TASK_UTRACED); - spin_unlock_irq(&target->sighand->siglock); - } - -@@ -710,7 +712,7 @@ static bool utrace_reset(struct task_struct *task, struct utrace *utrace) - /* - * If no more engines want it stopped, wake it up. - */ -- if (task_is_traced(task) && !(flags & ENGINE_STOP)) { -+ if (task_is_utraced(task) && !(flags & ENGINE_STOP)) { - /* - * It just resumes, so make sure single-step - * is not left set. -@@ -749,7 +751,7 @@ void utrace_finish_stop(void) - } - - /* -- * Perform %UTRACE_STOP, i.e. block in TASK_TRACED until woken up. -+ * Perform %UTRACE_STOP, i.e. block in TASK_UTRACED until woken up. - * @task == current, @utrace == current->utrace, which is not locked. - * Return true if we were woken up by SIGKILL even though some utrace - * engine may still want us to stay stopped. -@@ -799,7 +801,7 @@ relock: - return; - } - -- __set_current_state(TASK_TRACED); -+ __set_current_state(TASK_UTRACED); - - spin_unlock_irq(&task->sighand->siglock); - spin_unlock(&utrace->lock); -@@ -809,14 +811,14 @@ relock: - utrace_finish_stop(); - - /* -- * While in TASK_TRACED, we were considered "frozen enough". -+ * While in TASK_UTRACED, we were considered "frozen enough". - * Now that we woke up, it's crucial if we're supposed to be - * frozen that we freeze now before running anything substantial. - */ - try_to_freeze(); - - /* -- * While we were in TASK_TRACED, complete_signal() considered -+ * While we were in TASK_UTRACED, complete_signal() considered - * us "uninterested" in signal wakeups. Now make sure our - * TIF_SIGPENDING state is correct for normal running. - */ -@@ -1087,7 +1089,7 @@ int utrace_control(struct task_struct *target, - if (unlikely(IS_ERR(utrace))) - return PTR_ERR(utrace); - -- reset = task_is_traced(target); -+ reset = task_is_utraced(target); - ret = 0; - - /* --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:53 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:53 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B8F54D5296; - Mon, 21 Nov 2011 15:06:53 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id PX4Y3H1mw0hD; Mon, 21 Nov 2011 15:06:53 -0500 (EST) -Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id A4B5CD528E; - Mon, 21 Nov 2011 15:06:53 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK6pXd029643; - Mon, 21 Nov 2011 15:06:52 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:12 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:10 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 16/33] reintroduce tracehook_finish_jctl() as - utrace_end_stop() -Message-ID: <20111121200210.GA27829@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 -Status: RO -Content-Length: 2401 -Lines: 77 - -utrace_finish_stop() is needed to avoid the races with SIGKILL which -wakes up UTRACED task, and thus it should be called every time after -the STOPPED/TRACED/UTRACED returns from schedule(), remember that -TASK_UTRACED can be added while the task is STOPPED/UTRACED. - -- change do_signal_state() to call this helper right after schedule(), - otherwise this logic is broken by the upstream changes - -- now that utrace doesn't control TASK_TRACED bit, ptrace_stop() must - call this helper too. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/utrace.h | 11 +++++++++++ - kernel/signal.c | 5 +++++ - kernel/utrace.c | 2 +- - 3 files changed, 17 insertions(+), 1 deletions(-) - -diff --git a/include/linux/utrace.h b/include/linux/utrace.h -index cf13839..0279c74 100644 ---- a/include/linux/utrace.h -+++ b/include/linux/utrace.h -@@ -719,4 +719,15 @@ static inline void utrace_exit_notify(struct task_struct *task, - utrace_report_death(task, group_dead, signal); - } - -+/** -+ * utrace_end_stop - report about return from STOPPED/TRACED -+ * -+ * This is called by do_signal_stop() and ptrace_stop after wakeup. -+ */ -+static inline void utrace_end_stop(void) -+{ -+ if (task_utrace_flags(current)) -+ utrace_finish_stop(); -+} -+ - #endif /* linux/utrace.h */ -diff --git a/kernel/signal.c b/kernel/signal.c -index 7a47a93..ba46eab 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -1903,6 +1903,8 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) - read_unlock(&tasklist_lock); - } - -+ utrace_end_stop(); -+ - /* - * While in TASK_TRACED, we were considered "frozen enough". - * Now that we woke up, it's crucial if we're supposed to be -@@ -2067,6 +2069,9 @@ static bool do_signal_stop(int signr) - - /* Now we don't run again until woken by SIGCONT or SIGKILL */ - schedule(); -+ -+ utrace_end_stop(); -+ - return true; - } else { - /* -diff --git a/kernel/utrace.c b/kernel/utrace.c -index 2097103..d41b982 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -741,7 +741,7 @@ static bool utrace_reset(struct task_struct *task, struct utrace *utrace) - void utrace_finish_stop(void) - { - /* -- * If we were task_is_traced() and then SIGKILL'ed, make -+ * If we were task_is_utraced() and then SIGKILL'ed, make - * sure we do nothing until the tracer drops utrace->lock. - */ - if (unlikely(__fatal_signal_pending(current))) { --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:56 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:56 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 4A487D83A1; - Mon, 21 Nov 2011 15:06:56 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 3vHogPyhojlJ; Mon, 21 Nov 2011 15:06:56 -0500 (EST) -Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 358A0D88B0; - Mon, 21 Nov 2011 15:06:56 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK6sHk017679; - Mon, 21 Nov 2011 15:06:54 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:14 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:12 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 17/33] teach wake_up_quiescent() to do "selective" wake_up -Message-ID: <20111121200212.GA27836@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 -Status: RO -Content-Length: 1335 -Lines: 46 - -Both utrace and ptrace can want the same thread to be quiescent, in this -case its state is TASK_TRACED | TASK_UTRACED. And this also means that -this task must not run unless both utrace and ptrace resume it. - -Change wake_up_quiescent(p, state) to do "p->state &= ~state" and return -false unless there is no more "quiescent" bits in task->state. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/signal.c | 15 +++++++++++++++ - 1 files changed, 15 insertions(+), 0 deletions(-) - -diff --git a/kernel/signal.c b/kernel/signal.c -index ba46eab..e06f795 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -701,11 +701,26 @@ void signal_wake_up(struct task_struct *t, int resume) - kick_process(t); - } - -+#define STATE_QUIESCENT (__TASK_STOPPED | __TASK_TRACED | __TASK_UTRACED) - /* - * wakes up the STOPPED/TRACED task, must be called with ->siglock held. - */ - int wake_up_quiescent(struct task_struct *p, unsigned int state) - { -+ unsigned int quiescent = (p->state & STATE_QUIESCENT); -+ -+ WARN_ON(state & ~(STATE_QUIESCENT | TASK_INTERRUPTIBLE)); -+ -+ if (quiescent) { -+ state &= ~TASK_INTERRUPTIBLE; -+ if ((quiescent & ~state) != 0) { -+ p->state &= ~state; -+ WARN_ON(!(p->state & STATE_QUIESCENT)); -+ WARN_ON(!(p->state & TASK_WAKEKILL)); -+ return 0; -+ } -+ } -+ - return wake_up_state(p, state); - } - --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:06:59 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:06:58 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id C88E2D528B; - Mon, 21 Nov 2011 15:06:58 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id nNrAxBD5KOME; Mon, 21 Nov 2011 15:06:58 -0500 (EST) -Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B2114D51C1; - Mon, 21 Nov 2011 15:06:58 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK6uQQ031440; - Mon, 21 Nov 2011 15:06:57 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:17 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:15 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 18/33] ptrace_stop: do not assume the task is running after - wake_up_quiescent() -Message-ID: <20111121200215.GA27839@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 -Status: RO -Content-Length: 956 -Lines: 31 - -If ptrace_stop() sets TASK_TRACED and then detects we should not stop, -it can race with utrace_do_stop() which can see TASK_TRACED and add -TASK_UTRACED. In this case we should stop for utrace needs. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/signal.c | 8 ++++++++ - 1 files changed, 8 insertions(+), 0 deletions(-) - -diff --git a/kernel/signal.c b/kernel/signal.c -index e06f795..9348da6 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -1916,6 +1916,14 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) - if (clear_code) - current->exit_code = 0; - read_unlock(&tasklist_lock); -+ -+ /* -+ * It is possible that __TASK_UTRACED was added by utrace -+ * while we were __TASK_TRACED and before we take ->siglock -+ * for wake_up_quiescent(), we need to block in this case. -+ * Otherwise this is unnecessary but absolutely harmless. -+ */ -+ schedule(); - } - - utrace_end_stop(); --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:01 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:01 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 4BF37D889A; - Mon, 21 Nov 2011 15:07:01 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 5p8tvlXAqUHr; Mon, 21 Nov 2011 15:07:01 -0500 (EST) -Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 37C22D8757; - Mon, 21 Nov 2011 15:07:01 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK6xFJ031449; - Mon, 21 Nov 2011 15:06:59 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:19 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:18 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 19/33] get_signal_to_deliver: restore/restructure - utrace/ptrace signal reporting -Message-ID: <20111121200218.GA27846@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 -Status: RO -Content-Length: 3556 -Lines: 115 - -- Reintroduce tracehook_get_signal() as utrace_hook_signal(). - -- Change get_signal_to_deliver() to call utrace_hook_signal() first, - before dequeue_signal() - -- Always call ptrace_signal() if signal != SIGKILL, no matter whether - this signal comes from utrace or not. - - Since this can change signr again, update "struct k_sigaction *ka" - in this case. - -IOW, roughly, ptrace acts as if it is the last attached engine, it -takes the final decision about the signal. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/utrace.h | 31 +++++++++++++++++++++++++++++++ - kernel/signal.c | 30 ++++++++++++++++++++---------- - 2 files changed, 51 insertions(+), 10 deletions(-) - -diff --git a/include/linux/utrace.h b/include/linux/utrace.h -index 0279c74..63103e2 100644 ---- a/include/linux/utrace.h -+++ b/include/linux/utrace.h -@@ -730,4 +730,35 @@ static inline void utrace_end_stop(void) - utrace_finish_stop(); - } - -+/** -+ * utrace_hook_signal - deliver synthetic signal to traced task -+ * @task: @current -+ * @regs: task_pt_regs(@current) -+ * @info: details of synthetic signal -+ * @return_ka: sigaction for synthetic signal -+ * -+ * Return zero to check for a real pending signal normally. -+ * Return -1 after releasing the siglock to repeat the check. -+ * Return a signal number to induce an artificial signal delivery, -+ * setting *@info and *@return_ka to specify its details and behavior. -+ * -+ * The @return_ka->sa_handler value controls the disposition of the -+ * signal, no matter the signal number. For %SIG_DFL, the return value -+ * is a representative signal to indicate the behavior (e.g. %SIGTERM -+ * for death, %SIGQUIT for core dump, %SIGSTOP for job control stop, -+ * %SIGTSTP for stop unless in an orphaned pgrp), but the signal number -+ * reported will be @info->si_signo instead. -+ * -+ * Called with @task->sighand->siglock held, before dequeuing pending signals. -+ */ -+static inline int utrace_hook_signal(struct task_struct *task, -+ struct pt_regs *regs, -+ siginfo_t *info, -+ struct k_sigaction *return_ka) -+{ -+ if (unlikely(task_utrace_flags(task))) -+ return utrace_get_signal(task, regs, info, return_ka); -+ return 0; -+} -+ - #endif /* linux/utrace.h */ -diff --git a/kernel/signal.c b/kernel/signal.c -index 9348da6..38ea4e6 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -2242,17 +2242,27 @@ relock: - for (;;) { - struct k_sigaction *ka; - -- if (unlikely(current->jobctl & JOBCTL_STOP_PENDING) && -- do_signal_stop(0)) -+ signr = utrace_hook_signal(current, regs, info, return_ka); -+ if (unlikely(signr < 0)) - goto relock; - -- if (unlikely(current->jobctl & JOBCTL_TRAP_MASK)) { -- do_jobctl_trap(); -- spin_unlock_irq(&sighand->siglock); -- goto relock; -- } -+ if (unlikely(signr != 0)) -+ ka = return_ka; -+ else { -+ if (unlikely(current->jobctl & JOBCTL_STOP_PENDING) && -+ do_signal_stop(0)) -+ goto relock; - -- signr = dequeue_signal(current, ¤t->blocked, info); -+ if (unlikely(current->jobctl & JOBCTL_TRAP_MASK)) { -+ do_jobctl_trap(); -+ spin_unlock_irq(&sighand->siglock); -+ goto relock; -+ } -+ -+ signr = dequeue_signal(current, ¤t->blocked, info); -+ -+ ka = &sighand->action[signr-1]; -+ } - - if (!signr) - break; /* will return 0 */ -@@ -2262,9 +2272,9 @@ relock: - regs, cookie); - if (!signr) - continue; -- } - -- ka = &sighand->action[signr-1]; -+ ka = &sighand->action[signr-1]; -+ } - - /* Trace actually delivered signals. */ - trace_signal_deliver(signr, info, ka); --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:03 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:03 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id CB362D89E9; - Mon, 21 Nov 2011 15:07:03 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id wm2JqccPnhsV; Mon, 21 Nov 2011 15:07:03 -0500 (EST) -Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B6D25D89DE; - Mon, 21 Nov 2011 15:07:03 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK715f031455; - Mon, 21 Nov 2011 15:07:02 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:22 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:20 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 20/33] utrace_get_signal: - s/JOBCTL_STOP_PENDING/JOBCTL_PENDING_MASK/ -Message-ID: <20111121200220.GA27849@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 -Status: RO -Content-Length: 1204 -Lines: 33 - -utrace_get_signal() checks JOBCTL_STOP_PENDING to detect the -case when we should not try to dequeue the signal but should -try to participate in the group-stop. - -With the recent changes this is not enough, everything which -contrbutes to recalc_sigpending_tsk() should be respected. - -Check JOBCTL_PENDING_MASK instead. This matches the -JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK code in the caller, -get_signal_to_deliver(). Note that this code won't run if -utrace_get_signal() returns signr > 0. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/utrace.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/kernel/utrace.c b/kernel/utrace.c -index d41b982..0bb0a06 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -2027,7 +2027,7 @@ int utrace_get_signal(struct task_struct *task, struct pt_regs *regs, - ka = NULL; - memset(return_ka, 0, sizeof *return_ka); - } else if (!(task->utrace_flags & UTRACE_EVENT_SIGNAL_ALL) || -- unlikely(task->jobctl & JOBCTL_STOP_PENDING)) { -+ unlikely(task->jobctl & JOBCTL_PENDING_MASK)) { - /* - * If no engine is interested in intercepting signals or - * we must stop, let the caller just dequeue them normally --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:07 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:06 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 8C14BD4F84; - Mon, 21 Nov 2011 15:07:06 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 39eM-KKZxrZ3; Mon, 21 Nov 2011 15:07:06 -0500 (EST) -Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 7628FD4FF4; - Mon, 21 Nov 2011 15:07:06 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK74dN022253; - Mon, 21 Nov 2011 15:07:04 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:25 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:23 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 21/33] introduce ptrace_set_syscall_trace() -Message-ID: <20111121200223.GA27856@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 -Status: RO -Content-Length: 1549 -Lines: 52 - -No functional changes. Add the new helper, ptrace_set_syscall_trace(), -which should be used to set/clear TIF_SYSCALL_TRACE in ptrace code. -Currently it does nothing more. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/ptrace.c | 15 ++++++++++----- - 1 files changed, 10 insertions(+), 5 deletions(-) - -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index a464ab5..43357e5 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -38,6 +38,14 @@ void ptrace_signal_wake_up(struct task_struct *p, int quiescent) - kick_process(p); - } - -+static void ptrace_set_syscall_trace(struct task_struct *p, bool on) -+{ -+ if (on) -+ set_tsk_thread_flag(p, TIF_SYSCALL_TRACE); -+ else -+ clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); -+} -+ - static int ptrace_trapping_sleep_fn(void *flags) - { - schedule(); -@@ -418,7 +426,7 @@ static int ptrace_detach(struct task_struct *child, unsigned int data) - - /* Architecture-specific hardware disable .. */ - ptrace_disable(child); -- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); -+ ptrace_set_syscall_trace(child, false); - - write_lock_irq(&tasklist_lock); - /* -@@ -606,10 +614,7 @@ static int ptrace_resume(struct task_struct *child, long request, - if (!valid_signal(data)) - return -EIO; - -- if (request == PTRACE_SYSCALL) -- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); -- else -- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); -+ ptrace_set_syscall_trace(child, request == PTRACE_SYSCALL); - - #ifdef TIF_SYSCALL_EMU - if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP) --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:09 2011 -Return-Path: oleg@redhat.com -Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO - zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:09 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 1ADF01285E4; - Mon, 21 Nov 2011 15:07:09 -0500 (EST) -Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id rF+XegsxVXnL; Mon, 21 Nov 2011 15:07:09 -0500 (EST) -Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 067E41287D0; - Mon, 21 Nov 2011 15:07:09 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK76tD022270; - Mon, 21 Nov 2011 15:07:07 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:27 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:25 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 22/33] introduce PT_SYSCALL_TRACE flag -Message-ID: <20111121200225.GA27860@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 -Status: RO -Content-Length: 2268 -Lines: 73 - -Currently tracehooks assume that if the ptraced task has -TIF_SYSCALL_TRACE set, the tracee should report the syscall. -This is not true, this thread flag can be set by utrace. - -Add the new internal ptrace flag, PT_SYSCALL_TRACE. Change -ptrace_set_syscall_trace() to set/clear this bit along with -TIF_SYSCALL_TRACE, change ptrace_report_syscall() to check -this flag instead of PT_PTRACED. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/ptrace.h | 3 +++ - include/linux/tracehook.h | 2 +- - kernel/ptrace.c | 7 +++++-- - 3 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h -index 6d9282a..c10f610 100644 ---- a/include/linux/ptrace.h -+++ b/include/linux/ptrace.h -@@ -104,6 +104,8 @@ - - #define PT_TRACE_MASK 0x000003f4 - -+#define PT_SYSCALL_TRACE 0x00020000 -+ - /* single stepping state bits (used on ARM and PA-RISC) */ - #define PT_SINGLESTEP_BIT 31 - #define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT) -@@ -227,6 +229,7 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace) - - if (unlikely(ptrace) && current->ptrace) { - child->ptrace = current->ptrace; -+ child->ptrace &= ~PT_SYSCALL_TRACE; - __ptrace_link(child, current->parent); - - if (child->ptrace & PT_SEIZED) -diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h -index ec2af67..eb9fe30 100644 ---- a/include/linux/tracehook.h -+++ b/include/linux/tracehook.h -@@ -59,7 +59,7 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) - { - int ptrace = current->ptrace; - -- if (!(ptrace & PT_PTRACED)) -+ if (!(ptrace & PT_SYSCALL_TRACE)) - return; - - ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index 43357e5..1ac03eb 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -40,10 +40,13 @@ void ptrace_signal_wake_up(struct task_struct *p, int quiescent) - - static void ptrace_set_syscall_trace(struct task_struct *p, bool on) - { -- if (on) -+ if (on) { -+ p->ptrace |= PT_SYSCALL_TRACE; - set_tsk_thread_flag(p, TIF_SYSCALL_TRACE); -- else -+ } else { -+ p->ptrace &= ~PT_SYSCALL_TRACE; - clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); -+ } - } - - static int ptrace_trapping_sleep_fn(void *flags) --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:11 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:11 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B7D62D4DCC; - Mon, 21 Nov 2011 15:07:11 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 1ENpGO166I-W; Mon, 21 Nov 2011 15:07:11 -0500 (EST) -Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id A3A55D498A; - Mon, 21 Nov 2011 15:07:11 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK79AS017728; - Mon, 21 Nov 2011 15:07:10 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:30 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:28 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 23/33] utrace: don't clear TIF_SYSCALL_TRACE if it is - needed by ptrace -Message-ID: <20111121200228.GA27863@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 -Status: RO -Content-Length: 797 -Lines: 24 - -TIF_SYSCALL_TRACE should be cleared only if both ptrace and utrace do -not want it, change utrace_reset() to check PT_SYSCALL_TRACE before -clear_tsk_thread_flag(TIF_SYSCALL_TRACE). - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/utrace.c | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - -diff --git a/kernel/utrace.c b/kernel/utrace.c -index 0bb0a06..bebf6de 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -697,6 +697,7 @@ static bool utrace_reset(struct task_struct *task, struct utrace *utrace) - BUG_ON(utrace->death); - flags &= UTRACE_EVENT(REAP); - } else if (!(flags & UTRACE_EVENT_SYSCALL) && -+ !(task->ptrace & PT_SYSCALL_TRACE) && - test_tsk_thread_flag(task, TIF_SYSCALL_TRACE)) { - clear_tsk_thread_flag(task, TIF_SYSCALL_TRACE); - } --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:14 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:14 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 5376AD8774; - Mon, 21 Nov 2011 15:07:14 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 5Oc8ErfFfJSs; Mon, 21 Nov 2011 15:07:14 -0500 (EST) -Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 3F2CFD81E9; - Mon, 21 Nov 2011 15:07:14 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK7Cw3015467; - Mon, 21 Nov 2011 15:07:12 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:32 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:30 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 24/33] introduce task_utrace_lock/task_utrace_unlock -Message-ID: <20111121200230.GA27870@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 -Status: RO -Content-Length: 2190 -Lines: 81 - -- Add task_utrace_lock(task). It simply takes task->utrace->lock if - this task was ever utraced. Otherwise it takes task_lock(), this - serializes with utrace_attach_task()->utrace_task_alloc(). In both - case the caller can be sure it can't race with anything which needs - utrace->lock. - -- Add task_utrace_unlock(task), it releases the corresponding lock. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/utrace.h | 9 +++++++++ - kernel/utrace.c | 26 ++++++++++++++++++++++++++ - 2 files changed, 35 insertions(+), 0 deletions(-) - -diff --git a/include/linux/utrace.h b/include/linux/utrace.h -index 63103e2..f37373b 100644 ---- a/include/linux/utrace.h -+++ b/include/linux/utrace.h -@@ -117,6 +117,12 @@ void utrace_signal_handler(struct task_struct *, int); - - #ifndef CONFIG_UTRACE - -+static inline void task_utrace_lock(struct task_struct *task) -+{ -+} -+static inline void task_utrace_unlock(struct task_struct *task) -+{ -+} - /* - * <linux/tracehook.h> uses these accessors to avoid #ifdef CONFIG_UTRACE. - */ -@@ -139,6 +145,9 @@ static inline void task_utrace_proc_status(struct seq_file *m, - - #else /* CONFIG_UTRACE */ - -+extern void task_utrace_lock(struct task_struct *task); -+extern void task_utrace_unlock(struct task_struct *task); -+ - static inline unsigned long task_utrace_flags(struct task_struct *task) - { - return task->utrace_flags; -diff --git a/kernel/utrace.c b/kernel/utrace.c -index bebf6de..960dd9e 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -79,6 +79,32 @@ static int __init utrace_init(void) - } - module_init(utrace_init); - -+void task_utrace_lock(struct task_struct *task) -+{ -+ struct utrace *utrace = task_utrace_struct(task); -+ -+ if (!utrace) { -+ task_lock(task); -+ utrace = task_utrace_struct(task); -+ if (!utrace) -+ return; -+ -+ task_unlock(task); -+ } -+ -+ spin_lock(&utrace->lock); -+} -+ -+void task_utrace_unlock(struct task_struct *task) -+{ -+ struct utrace *utrace = task_utrace_struct(task); -+ -+ if (utrace) -+ spin_unlock(&utrace->lock); -+ else -+ task_unlock(task); -+} -+ - /* - * Set up @task.utrace for the first time. We can have races - * between two utrace_attach_task() calls here. The task_lock() --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:17 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:17 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 01034D498A; - Mon, 21 Nov 2011 15:07:17 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id BglmrU3H2hJr; Mon, 21 Nov 2011 15:07:16 -0500 (EST) -Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id E0D31D4FF4; - Mon, 21 Nov 2011 15:07:16 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK7Egx015474; - Mon, 21 Nov 2011 15:07:15 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:35 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:33 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 25/33] teach ptrace_set_syscall_trace() to play well with - utrace -Message-ID: <20111121200233.GA27873@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 -Status: RO -Content-Length: 1545 -Lines: 49 - -1. ptrace_set_syscall_trace(true)->set_tsk_thread_flag(TIF_SYSCALL_TRACE) - can race with utrace_control()->utrace_reset() path which can miss - PT_SYSCALL_TRACE and clear TIF_SYSCALL_TRACE after it was already set. - -2. ptrace_set_syscall_trace(false) clears TIF_SYSCALL_TRACE and this is - not utrace-friendly, it can need this flag. - -Change ptrace_set_syscall_trace() to take task_utrace_lock(), this is -enough to fix the 1st problem. Check task_utrace_flags() before clearing -TIF_SYSCALL_TRACE, this fixes 2. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/ptrace.c | 6 +++++- - 1 files changed, 5 insertions(+), 1 deletions(-) - -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index 1ac03eb..739183a 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -24,6 +24,7 @@ - #include <linux/regset.h> - #include <linux/hw_breakpoint.h> - #include <linux/cn_proc.h> -+#include <linux/utrace.h> - - void ptrace_signal_wake_up(struct task_struct *p, int quiescent) - { -@@ -40,13 +41,16 @@ void ptrace_signal_wake_up(struct task_struct *p, int quiescent) - - static void ptrace_set_syscall_trace(struct task_struct *p, bool on) - { -+ task_utrace_lock(p); - if (on) { - p->ptrace |= PT_SYSCALL_TRACE; - set_tsk_thread_flag(p, TIF_SYSCALL_TRACE); - } else { - p->ptrace &= ~PT_SYSCALL_TRACE; -- clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); -+ if (!(task_utrace_flags(p) & UTRACE_EVENT_SYSCALL)) -+ clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); - } -+ task_utrace_unlock(p); - } - - static int ptrace_trapping_sleep_fn(void *flags) --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:19 2011 -Return-Path: oleg@redhat.com -Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO - zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:19 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 8F87F128EAA; - Mon, 21 Nov 2011 15:07:19 -0500 (EST) -Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id yittEjCd+X4F; Mon, 21 Nov 2011 15:07:19 -0500 (EST) -Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 7BC701287D0; - Mon, 21 Nov 2011 15:07:19 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK7HbH031553; - Mon, 21 Nov 2011 15:07:18 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:38 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:36 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 26/33] introduce PT_SINGLE_STEP and PT_SINGLE_BLOCK -Message-ID: <20111121200236.GA27880@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 -Status: RO -Content-Length: 3723 -Lines: 108 - -Add the new internal ptrace flags, PT_SINGLE_STEP and PT_SINGLE_BLOCK. - -Like PT_SYSCALL_TRACE, this is needed to avoid the unnecessary ptrace -reports when TIF_SINGLESTEP was set by another engine, not by ptrace. -Also, we need these bits to coordinate the user_*_single_step() calls -from ptrace and utrace. - -TODO: update the !x86 ptrace code which does user_disable_single_step(). - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - arch/x86/kernel/ptrace.c | 1 + - include/linux/ptrace.h | 5 ++++- - include/linux/tracehook.h | 7 +++++-- - kernel/ptrace.c | 3 +++ - 4 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c -index 8252879..d1557dc 100644 ---- a/arch/x86/kernel/ptrace.c -+++ b/arch/x86/kernel/ptrace.c -@@ -808,6 +808,7 @@ static int ioperm_get(struct task_struct *target, - */ - void ptrace_disable(struct task_struct *child) - { -+ child->ptrace &= ~(PT_SINGLE_STEP | PT_SINGLE_BLOCK); - user_disable_single_step(child); - #ifdef TIF_SYSCALL_EMU - clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); -diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h -index c10f610..2743315 100644 ---- a/include/linux/ptrace.h -+++ b/include/linux/ptrace.h -@@ -105,6 +105,8 @@ - #define PT_TRACE_MASK 0x000003f4 - - #define PT_SYSCALL_TRACE 0x00020000 -+#define PT_SINGLE_STEP 0x00040000 -+#define PT_SINGLE_BLOCK 0x00080000 - - /* single stepping state bits (used on ARM and PA-RISC) */ - #define PT_SINGLESTEP_BIT 31 -@@ -229,7 +231,8 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace) - - if (unlikely(ptrace) && current->ptrace) { - child->ptrace = current->ptrace; -- child->ptrace &= ~PT_SYSCALL_TRACE; -+ child->ptrace &= -+ ~(PT_SYSCALL_TRACE | PT_SINGLE_STEP | PT_SINGLE_BLOCK); - __ptrace_link(child, current->parent); - - if (child->ptrace & PT_SEIZED) -diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h -index eb9fe30..21c8ca2 100644 ---- a/include/linux/tracehook.h -+++ b/include/linux/tracehook.h -@@ -104,6 +104,9 @@ static inline __must_check int tracehook_report_syscall_entry( - return 0; - } - -+#define ptrace_wants_step() \ -+ (current->ptrace & (PT_SINGLE_STEP | PT_SINGLE_BLOCK)) -+ - /** - * tracehook_report_syscall_exit - task has just finished a system call - * @regs: user register state of current task -@@ -126,7 +129,7 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) - if (task_utrace_flags(current) & UTRACE_EVENT(SYSCALL_EXIT)) - utrace_report_syscall_exit(regs); - -- if (step) { -+ if (step && ptrace_wants_step()) { - siginfo_t info; - user_single_step_siginfo(current, regs, &info); - force_sig_info(SIGTRAP, &info, current); -@@ -157,7 +160,7 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, - { - if (task_utrace_flags(current)) - utrace_signal_handler(current, stepping); -- if (stepping) -+ if (stepping && ptrace_wants_step()) - ptrace_notify(SIGTRAP); - } - -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index 739183a..792080d 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -630,13 +630,16 @@ static int ptrace_resume(struct task_struct *child, long request, - clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); - #endif - -+ child->ptrace &= ~(PT_SINGLE_STEP | PT_SINGLE_BLOCK); - if (is_singleblock(request)) { - if (unlikely(!arch_has_block_step())) - return -EIO; -+ child->ptrace |= PT_SINGLE_BLOCK; - user_enable_block_step(child); - } else if (is_singlestep(request) || is_sysemu_singlestep(request)) { - if (unlikely(!arch_has_single_step())) - return -EIO; -+ child->ptrace |= PT_SINGLE_STEP; - user_enable_single_step(child); - } else { - user_disable_single_step(child); --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:22 2011 -Return-Path: oleg@redhat.com -Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO - zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:22 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 0C136128FB0; - Mon, 21 Nov 2011 15:07:22 -0500 (EST) -Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id GNbS20gY5Jq9; Mon, 21 Nov 2011 15:07:21 -0500 (EST) -Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id EB5821287D0; - Mon, 21 Nov 2011 15:07:21 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK7Kn1029766; - Mon, 21 Nov 2011 15:07:20 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:40 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:38 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 27/33] utrace: finish_resume_report: don't do - user_xxx_step() if ptrace_wants_step() -Message-ID: <20111121200238.GA27883@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 -Status: RO -Content-Length: 2741 -Lines: 84 - -finish_resume_report() should not enable/disable the stepping if -ptrace_wants_step() == T. If ptrace wants block_step while utrace -wants single_step we could "promote" the stepping, but I do not -think this really makes sense. - -Unless the tracee is killed this can't race with ptrace, this is -called by the tracee itself. If it is killed we do not care. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/tracehook.h | 8 ++++---- - kernel/utrace.c | 9 ++++++--- - 2 files changed, 10 insertions(+), 7 deletions(-) - -diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h -index 21c8ca2..b6812d4 100644 ---- a/include/linux/tracehook.h -+++ b/include/linux/tracehook.h -@@ -104,8 +104,8 @@ static inline __must_check int tracehook_report_syscall_entry( - return 0; - } - --#define ptrace_wants_step() \ -- (current->ptrace & (PT_SINGLE_STEP | PT_SINGLE_BLOCK)) -+#define ptrace_wants_step(task) \ -+ ((task)->ptrace & (PT_SINGLE_STEP | PT_SINGLE_BLOCK)) - - /** - * tracehook_report_syscall_exit - task has just finished a system call -@@ -129,7 +129,7 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) - if (task_utrace_flags(current) & UTRACE_EVENT(SYSCALL_EXIT)) - utrace_report_syscall_exit(regs); - -- if (step && ptrace_wants_step()) { -+ if (step && ptrace_wants_step(current)) { - siginfo_t info; - user_single_step_siginfo(current, regs, &info); - force_sig_info(SIGTRAP, &info, current); -@@ -160,7 +160,7 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, - { - if (task_utrace_flags(current)) - utrace_signal_handler(current, stepping); -- if (stepping && ptrace_wants_step()) -+ if (stepping && ptrace_wants_step(current)) - ptrace_notify(SIGTRAP); - } - -diff --git a/kernel/utrace.c b/kernel/utrace.c -index 960dd9e..05e8532 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -1829,7 +1829,8 @@ static void finish_resume_report(struct task_struct *task, - - case UTRACE_BLOCKSTEP: - if (likely(arch_has_block_step())) { -- user_enable_block_step(task); -+ if (!ptrace_wants_step(task)) -+ user_enable_block_step(task); - break; - } - -@@ -1842,7 +1843,8 @@ static void finish_resume_report(struct task_struct *task, - - case UTRACE_SINGLESTEP: - if (likely(arch_has_single_step())) { -- user_enable_single_step(task); -+ if (!ptrace_wants_step(task)) -+ user_enable_single_step(task); - } else { - /* - * This means some callback is to blame for failing -@@ -1857,7 +1859,8 @@ static void finish_resume_report(struct task_struct *task, - case UTRACE_REPORT: - case UTRACE_RESUME: - default: -- user_disable_single_step(task); -+ if (!ptrace_wants_step(task)) -+ user_disable_single_step(task); - break; - } - } --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:24 2011 -Return-Path: oleg@redhat.com -Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO - zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:24 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 8954F12914D; - Mon, 21 Nov 2011 15:07:24 -0500 (EST) -Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 0lU8wXKC78yu; Mon, 21 Nov 2011 15:07:24 -0500 (EST) -Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 759B61287D0; - Mon, 21 Nov 2011 15:07:24 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK7Mi7022329; - Mon, 21 Nov 2011 15:07:23 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:43 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:41 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 28/33] ptrace: shift user_*_step() from ptrace_resume() to - ptrace_stop() -Message-ID: <20111121200241.GA27890@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 -Status: RO -Content-Length: 2374 -Lines: 70 - -1. ptrace_resume() plays with the stopped task which can be also - task_is_utraced(). In this case user_enable_xxx_step() can race - with utrace_reset()->user_disable_single_step(). - - We could change utrace_reset() to check ptrace_wants_step() and - add the task_utrace_lock + unlock barrier after ptrace_resume() - sets PT_SINGLE_STEP. - - But it is better to reassign enable/desable from the tracer to - the tracee, it can check its PT_SINGLE_ bits after wakeup. This - also makes sense because enable_step(task) can be faster if - task == current. - -2. ptrace can do user_disable_single_step() while utrace needs the - stepping. - - Set TIF_NOTIFY_RESUME after user_disable_single_step() to ensure - the tracee can't return to the user-space without utrace_resume(). - Any correct engine which wants the stepping should reassert it. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/ptrace.c | 4 ---- - kernel/signal.c | 11 +++++++++++ - 2 files changed, 11 insertions(+), 4 deletions(-) - -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index 792080d..eba9a22 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -635,14 +635,10 @@ static int ptrace_resume(struct task_struct *child, long request, - if (unlikely(!arch_has_block_step())) - return -EIO; - child->ptrace |= PT_SINGLE_BLOCK; -- user_enable_block_step(child); - } else if (is_singlestep(request) || is_sysemu_singlestep(request)) { - if (unlikely(!arch_has_single_step())) - return -EIO; - child->ptrace |= PT_SINGLE_STEP; -- user_enable_single_step(child); -- } else { -- user_disable_single_step(child); - } - - child->exit_code = data; -diff --git a/kernel/signal.c b/kernel/signal.c -index 38ea4e6..b13d2bc 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -1928,6 +1928,17 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) - - utrace_end_stop(); - -+ if (current->ptrace & PT_SINGLE_BLOCK) -+ user_enable_block_step(current); -+ else if (current->ptrace & PT_SINGLE_STEP) -+ user_enable_single_step(current); -+ else { -+ user_disable_single_step(current); -+ /* if utrace needs the stepping it should reassert */ -+ if (task_utrace_flags(current)) -+ set_thread_flag(TIF_NOTIFY_RESUME); -+ } -+ - /* - * While in TASK_TRACED, we were considered "frozen enough". - * Now that we woke up, it's crucial if we're supposed to be --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:27 2011 -Return-Path: oleg@redhat.com -Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO - zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:27 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 043581287D0; - Mon, 21 Nov 2011 15:07:27 -0500 (EST) -Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 4WO1El1jiIrJ; Mon, 21 Nov 2011 15:07:26 -0500 (EST) -Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id E3FCA129045; - Mon, 21 Nov 2011 15:07:26 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK7OdV017836; - Mon, 21 Nov 2011 15:07:25 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:45 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:43 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 29/33] ptrace_disable: no need to disable stepping -Message-ID: <20111121200243.GA27893@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 -Status: RO -Content-Length: 945 -Lines: 29 - -ptrace_disable() is called when the tracee is quiescent and we -are going to untrace. This means we are going to clear ->ptrace -and wake up the tracee. Now that ptrace_stop() checks PT_ bits -and does user_disable_single_step() we can remove this code from -ptrace_disable(), it is unneeded and not utrace-friendly. - -TODO: change !x86 code. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - arch/x86/kernel/ptrace.c | 2 -- - 1 files changed, 0 insertions(+), 2 deletions(-) - -diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c -index d1557dc..96d315a 100644 ---- a/arch/x86/kernel/ptrace.c -+++ b/arch/x86/kernel/ptrace.c -@@ -808,8 +808,6 @@ static int ioperm_get(struct task_struct *target, - */ - void ptrace_disable(struct task_struct *child) - { -- child->ptrace &= ~(PT_SINGLE_STEP | PT_SINGLE_BLOCK); -- user_disable_single_step(child); - #ifdef TIF_SYSCALL_EMU - clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); - #endif --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:29 2011 -Return-Path: oleg@redhat.com -Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO - zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:29 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 8A6E8D4C39; - Mon, 21 Nov 2011 15:07:29 -0500 (EST) -Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id NLURBx2yQes5; Mon, 21 Nov 2011 15:07:29 -0500 (EST) -Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) - by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 7660DD498A; - Mon, 21 Nov 2011 15:07:29 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK7RnP015578; - Mon, 21 Nov 2011 15:07:27 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:48 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:46 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 30/33] ptrace_report_syscall: check TIF_SYSCALL_EMU -Message-ID: <20111121200246.GA27896@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 -Status: RO -Content-Length: 858 -Lines: 28 - -4d16a64 "introduce PT_SYSCALL_TRACE flag" breaks PTRACE_SYSEMU -which doesn't set PT_SYSCALL_TRACE. - -Change ptrace_report_syscall() to check TIF_SYSCALL_EMU as well. -This can't conflict with utrace, this flag can only be set by -ptrace. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/tracehook.h | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h -index b6812d4..90ca578 100644 ---- a/include/linux/tracehook.h -+++ b/include/linux/tracehook.h -@@ -59,7 +59,7 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) - { - int ptrace = current->ptrace; - -- if (!(ptrace & PT_SYSCALL_TRACE)) -+ if (!(ptrace & PT_SYSCALL_TRACE) && !test_thread_flag(TIF_SYSCALL_EMU)) - return; - - ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:32 2011 -Return-Path: oleg@redhat.com -Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO - zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:32 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 10D1312916C; - Mon, 21 Nov 2011 15:07:32 -0500 (EST) -Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id Z14plX1oxaYL; Mon, 21 Nov 2011 15:07:32 -0500 (EST) -Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) - by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id F12FF128E1D; - Mon, 21 Nov 2011 15:07:31 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK7T0q022460; - Mon, 21 Nov 2011 15:07:30 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:50 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:48 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 31/33] utrace_resume: check irqs_disabled() to shut up - lockdep -Message-ID: <20111121200248.GA27903@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 -Status: RO -Content-Length: 823 -Lines: 26 - -utrace_resume() enables irqs unconditionally. With the recent changes -in lockdep.c this triggers the warning. Check irqs_disabled() before -local_irq_enable(). - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - kernel/utrace.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/kernel/utrace.c b/kernel/utrace.c -index 05e8532..c817a46 100644 ---- a/kernel/utrace.c -+++ b/kernel/utrace.c -@@ -1881,7 +1881,8 @@ void utrace_resume(struct task_struct *task, struct pt_regs *regs) - * code path leads to calling into get_signal_to_deliver(), which - * implicitly reenables them by virtue of spin_unlock_irq. - */ -- local_irq_enable(); -+ if (irqs_disabled()) /* make trace_hardirqs_on() happy */ -+ local_irq_enable(); - - /* - * If this flag is still set it's because there was a signal --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:34 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:34 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 860BCD8A3E; - Mon, 21 Nov 2011 15:07:34 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id pVTbN1oF62dg; Mon, 21 Nov 2011 15:07:34 -0500 (EST) -Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 6FBFFD87A3; - Mon, 21 Nov 2011 15:07:34 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id pALK7W0B029871; - Mon, 21 Nov 2011 15:07:32 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:53 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:51 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 32/33] ptrace_report_syscall: check if TIF_SYSCALL_EMU is - defined -Message-ID: <20111121200251.GA27906@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 -Status: RO -Content-Length: 839 -Lines: 31 - -From: Tony Breeds <tony@bakeyournoodle.com> - -TIF_SYSCALL_EMU is x86 only, add ifdef into ptrace_report_syscall(). - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - include/linux/tracehook.h | 8 ++++++-- - 1 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h -index 90ca578..a1bac95 100644 ---- a/include/linux/tracehook.h -+++ b/include/linux/tracehook.h -@@ -59,8 +59,12 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) - { - int ptrace = current->ptrace; - -- if (!(ptrace & PT_SYSCALL_TRACE) && !test_thread_flag(TIF_SYSCALL_EMU)) -- return; -+ if (!(ptrace & PT_SYSCALL_TRACE)) { -+#ifdef TIF_SYSCALL_EMU -+ if (!test_thread_flag(TIF_SYSCALL_EMU)) -+#endif -+ return; -+ } - - ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); - --- -1.5.5.1 - - -From oleg@redhat.com Mon Nov 21 15:07:37 2011 -Return-Path: oleg@redhat.com -Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO - zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by - zmail13.collab.prod.int.phx2.redhat.com with LMTP; Mon, 21 Nov 2011 - 15:07:37 -0500 (EST) -Received: from localhost (localhost.localdomain [127.0.0.1]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 33405D8A50; - Mon, 21 Nov 2011 15:07:37 -0500 (EST) -Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) - by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 3WH8FhvizjEA; Mon, 21 Nov 2011 15:07:37 -0500 (EST) -Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) - by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 1274FD89BB; - Mon, 21 Nov 2011 15:07:37 -0500 (EST) -Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) - by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id pALK7YHr017898; - Mon, 21 Nov 2011 15:07:35 -0500 -Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 - oleg@redhat.com; Mon, 21 Nov 2011 21:02:55 +0100 (CET) -Date: Mon, 21 Nov 2011 21:02:53 +0100 -From: Oleg Nesterov <oleg@redhat.com> -To: Dave Jones <davej@redhat.com>, "Frank Ch. Eigler" <fche@redhat.com>, - Josh Boyer <jwboyer@redhat.com>, Josh Stone <jistone@redhat.com>, - Kyle McMartin <kmcmartin@redhat.com> -Cc: kernel@lists.fedoraproject.org -Subject: [PATCH 33/33] utrace: s390: fix the compile problem with traps.c -Message-ID: <20111121200253.GA27913@redhat.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <20111121200039.GA27699@redhat.com> -User-Agent: Mutt/1.5.18 (2008-05-17) -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 -Status: RO -Content-Length: 725 -Lines: 25 - -d99e60e5 "tracehooks: reintroduce tracehook_consider_fatal_signal()" -breaks the compilation of arch/s390/kernel/traps.c. Restore the -necessary include removed by upstream 73b7d40f commit. - -Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---- - arch/s390/kernel/traps.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c -index f506e1b..3132498 100644 ---- a/arch/s390/kernel/traps.c -+++ b/arch/s390/kernel/traps.c -@@ -18,7 +18,7 @@ - #include <linux/kernel.h> - #include <linux/string.h> - #include <linux/errno.h> --#include <linux/ptrace.h> -+#include <linux/tracehook.h> - #include <linux/timer.h> - #include <linux/mm.h> - #include <linux/smp.h> --- -1.5.5.1 - |