rpms/kernel/F-11 kernel.spec, 1.1629, 1.1630 linux-2.6-tracehook.patch, 1.8, 1.9 linux-2.6-utrace.patch, 1.110, 1.111
Roland McGrath
roland at fedoraproject.org
Tue Jun 2 20:45:27 UTC 2009
Author: roland
Update of /cvs/pkgs/rpms/kernel/F-11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv10766
Modified Files:
kernel.spec linux-2.6-tracehook.patch linux-2.6-utrace.patch
Log Message:
utrace update (fixes stap PR10185)
Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/kernel.spec,v
retrieving revision 1.1629
retrieving revision 1.1630
diff -u -p -r1.1629 -r1.1630
--- kernel.spec 27 May 2009 21:03:13 -0000 1.1629
+++ kernel.spec 2 Jun 2009 20:44:55 -0000 1.1630
@@ -2019,7 +2019,10 @@ fi
# and build.
%changelog
-* Wed May 27 2009 Kristian Høgsberg <krh at madara.bos.redhat.com> - 2.6.4.167
+* Tue Jun 2 2009 Roland McGrath <roland at redhat.com> - 2.6.29.4-168
+- utrace update (fixes stap PR10185)
+
+* Wed May 27 2009 Kristian Høgsberg <krh at redhat.com> - 2.6.29.4-167
- Actually disable drm-intel-disable-kms-i8xx.patch.
* Wed May 27 2009 Kristian Høgsberg <krh at redhat.com> - 2.6.29.4-166
@@ -2031,7 +2034,7 @@ fi
* Wed May 27 2009 Kyle McMartin <kyle at redhat.com> 2.6.29.4-165
- Enable KMS/gem on I865.
- drm-no-gem-on-i8xx.patch: Remove I865 so GEM will be enabled.
-- drm-intel-disable-kms-i8xx.patch: Enable KMS on I865.
+- drm-intel-disable-kms-i8xx.patch: Enable KMS on I865.
- Two fixes from Eric Anholt to fix i8x5:
drm-i915-apply-a-big-hammer-to-865-gem-object.patch
drm-i915-fix-tiling-pitch.patch
@@ -2039,7 +2042,7 @@ fi
* Wed May 27 2009 Kyle McMartin <kyle at redhat.com> 2.6.29.4-164
- drm-intel-disable-kms-i8xx.patch: disable KMS by default on 845, 855,
and 865. It can be forced on with i915.modeset=1 boot parameter.
-
+
* Tue May 26 2009 Ben Skeggs <bskeggs at redhat.com> 2.6.29.4-163
- drm-nouveau.patch: fix sor dpms (rh#501877)
@@ -2055,7 +2058,7 @@ fi
linux-2.6-btrfs-fix-page-mkwrite.patch
- rebased patches:
linux-2.6-btrfs-unstable-update.patch, page_mkwrite fixes.
-
+
* Mon May 25 2009 Kyle McMartin <kyle at redhat.com> 2.6.29.3-160
- kvm fixes destined for 2.6.30, rhbz#492838:
kvm-Fix-PDPTR-reloading-on-CR4-writes.patch
linux-2.6-tracehook.patch:
Index: linux-2.6-tracehook.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/linux-2.6-tracehook.patch,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -p -r1.8 -r1.9
--- linux-2.6-tracehook.patch 19 Mar 2009 08:03:53 -0000 1.8
+++ linux-2.6-tracehook.patch 2 Jun 2009 20:44:55 -0000 1.9
@@ -70,7 +70,7 @@ index 6186a78..b622498 100644
#define DEATH_REAP -1
diff --git a/kernel/signal.c b/kernel/signal.c
-index 2a74fe8..9a0d98f 100644
+index 1c88144..1adbb90 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -691,7 +691,7 @@ static int prepare_signal(int sig, struc
@@ -82,7 +82,7 @@ index 2a74fe8..9a0d98f 100644
* will take ->siglock, notice SIGNAL_CLD_MASK, and
* notify its parent. See get_signal_to_deliver().
*/
-@@ -1629,29 +1629,6 @@ void ptrace_notify(int exit_code)
+@@ -1637,29 +1637,6 @@ void ptrace_notify(int exit_code)
spin_unlock_irq(¤t->sighand->siglock);
}
@@ -112,7 +112,7 @@ index 2a74fe8..9a0d98f 100644
/*
* This performs the stopping for SIGSTOP and other stop signals.
* We have to stop all threads in the thread group.
-@@ -1662,6 +1639,7 @@ static int do_signal_stop(int signr)
+@@ -1670,6 +1647,7 @@ static int do_signal_stop(int signr)
{
struct signal_struct *sig = current->signal;
int stop_count;
@@ -120,7 +120,7 @@ index 2a74fe8..9a0d98f 100644
if (sig->group_stop_count > 0) {
/*
-@@ -1701,8 +1679,30 @@ static int do_signal_stop(int signr)
+@@ -1709,8 +1687,30 @@ static int do_signal_stop(int signr)
current->exit_code = sig->group_exit_code;
__set_current_state(TASK_STOPPED);
@@ -152,7 +152,7 @@ index 2a74fe8..9a0d98f 100644
return 1;
}
-@@ -1771,14 +1771,15 @@ relock:
+@@ -1779,14 +1779,15 @@ relock:
int why = (signal->flags & SIGNAL_STOP_CONTINUED)
? CLD_CONTINUED : CLD_STOPPED;
signal->flags &= ~SIGNAL_CLD_MASK;
@@ -174,7 +174,7 @@ index 2a74fe8..9a0d98f 100644
goto relock;
}
-@@ -1936,14 +1937,14 @@ void exit_signals(struct task_struct *ts
+@@ -1944,14 +1945,14 @@ void exit_signals(struct task_struct *ts
if (unlikely(tsk->signal->group_stop_count) &&
!--tsk->signal->group_stop_count) {
tsk->signal->flags = SIGNAL_STOP_STOPPED;
linux-2.6-utrace.patch:
Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/linux-2.6-utrace.patch,v
retrieving revision 1.110
retrieving revision 1.111
diff -u -p -r1.110 -r1.111
--- linux-2.6-utrace.patch 9 May 2009 02:08:24 -0000 1.110
+++ linux-2.6-utrace.patch 2 Jun 2009 20:44:55 -0000 1.111
@@ -25,8 +25,22 @@ the utrace API.
Signed-off-by: Roland McGrath <roland at redhat.com>
---
+ Documentation/DocBook/Makefile | 2 +-
+ Documentation/DocBook/utrace.tmpl | 590 ++++++++++
+ fs/proc/array.c | 3 +
+ include/linux/init_task.h | 1 +
+ include/linux/sched.h | 6 +
+ include/linux/tracehook.h | 61 +-
+ include/linux/utrace.h | 692 +++++++++++
+ include/linux/utrace_struct.h | 58 +
+ init/Kconfig | 9 +
+ kernel/Makefile | 1 +
+ kernel/ptrace.c | 18 +-
+ kernel/utrace.c | 2357 +++++++++++++++++++++++++++++++++++++
+ 12 files changed, 3795 insertions(+), 3 deletions(-)
+
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
-index 1462ed8..f5da1b4 100644
+index 1462ed8..f5da1b4 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -9,7 +9,7 @@
@@ -40,10 +54,10 @@ index 1462ed8..f5da1b4 100644
mac80211.xml debugobjects.xml sh.xml regulator.xml
diff --git a/Documentation/DocBook/utrace.tmpl b/Documentation/DocBook/utrace.tmpl
new file mode 100644
-index 0000000..b802c55
+index ...6cc58a1 100644
--- /dev/null
+++ b/Documentation/DocBook/utrace.tmpl
-@@ -0,0 +1,571 @@
+@@ -0,0 +1,590 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
@@ -109,12 +123,12 @@ index 0000000..b802c55
+ <para>
+ Many engines can be attached to each thread. When a thread has an
+ event, each engine gets a callback if it has set the event flag for
-+ that event type. Engines are called in the order they attached.
-+ Engines that attach after the event has occurred do not get callbacks
-+ for that event. This includes any new engines just attached by an
-+ existing engine's callback function. Once the sequence of callbacks
-+ for that one event has completed, such new engines are then eligible in
-+ the next sequence that starts when there is another event.
++ that event type. For most events, engines are called in the order they
++ attached. Engines that attach after the event has occurred do not get
++ callbacks for that event. This includes any new engines just attached
++ by an existing engine's callback function. Once the sequence of
++ callbacks for that one event has completed, such new engines are then
++ eligible in the next sequence that starts when there is another event.
+ </para>
+
+ <para>
@@ -132,6 +146,25 @@ index 0000000..b802c55
+ <function>utrace_control</function> to resume the thread.
+ </para>
+
++ <para>
++ The <constant>UTRACE_EVENT(SYSCALL_ENTRY)</constant> event is a special
++ case. While other events happen in the kernel when it will return to
++ user mode soon, this event happens when entering the kernel before it
++ will proceed with the work requested from user mode. Because of this
++ difference, the <function>report_syscall_entry</function> callback is
++ special in two ways. For this event, engines are called in reverse of
++ the normal order (this includes the <function>report_quiesce</function>
++ call that precedes a <function>report_syscall_entry</function> call).
++ This preserves the semantics that the last engine to attach is called
++ "closest to user mode"--the engine that is first to see a thread's user
++ state when it enters the kernel is also the last to see that state when
++ the thread returns to user mode. For the same reason, if these
++ callbacks use <constant>UTRACE_STOP</constant> (see the next section),
++ the thread stops immediately after callbacks rather than only when it's
++ ready to return to user mode; when allowed to resume, it will actually
++ attempt the system call indicated by the register values at that time.
++ </para>
++
+ </sect1>
+
+ <sect1 id="safely"><title>Stopping Safely</title>
@@ -616,7 +649,7 @@ index 0000000..b802c55
+
+</book>
diff --git a/fs/proc/array.c b/fs/proc/array.c
-index 725a650..e299a63 100644
+index 725a650..e299a63 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -82,6 +82,7 @@
@@ -627,7 +660,7 @@ index 725a650..e299a63 100644
#include <asm/pgtable.h>
#include <asm/processor.h>
-@@ -188,6 +189,8 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
+@@ -188,6 +189,8 @@ static inline void task_state(struct seq
cred->uid, cred->euid, cred->suid, cred->fsuid,
cred->gid, cred->egid, cred->sgid, cred->fsgid);
@@ -637,7 +670,7 @@ index 725a650..e299a63 100644
if (p->files)
fdt = files_fdtable(p->files);
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
-index e752d97..39eebc8 100644
+index e752d97..39eebc8 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -181,6 +181,7 @@ extern struct cred init_cred;
@@ -649,7 +682,7 @@ index e752d97..39eebc8 100644
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index f8af167..454de2a 100644
+index f8af167..454de2a 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -59,6 +59,7 @@ struct sched_param {
@@ -673,7 +706,7 @@ index f8af167..454de2a 100644
u32 parent_exec_id;
u32 self_exec_id;
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
-index b622498..6ff7277 100644
+index b622498..8def62a 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -49,6 +49,7 @@
@@ -693,7 +726,7 @@ index b622498..6ff7277 100644
return (task_ptrace(task) & PT_PTRACED) != 0;
}
-@@ -111,6 +114,9 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
+@@ -111,6 +114,9 @@ static inline void ptrace_report_syscall
static inline __must_check int tracehook_report_syscall_entry(
struct pt_regs *regs)
{
@@ -703,7 +736,7 @@ index b622498..6ff7277 100644
ptrace_report_syscall(regs);
return 0;
}
-@@ -134,6 +140,8 @@ static inline __must_check int tracehook_report_syscall_entry(
+@@ -134,6 +140,8 @@ static inline __must_check int tracehook
*/
static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
{
@@ -712,7 +745,7 @@ index b622498..6ff7277 100644
ptrace_report_syscall(regs);
}
-@@ -194,6 +202,8 @@ static inline void tracehook_report_exec(struct linux_binfmt *fmt,
+@@ -194,6 +202,8 @@ static inline void tracehook_report_exec
struct linux_binprm *bprm,
struct pt_regs *regs)
{
@@ -721,7 +754,7 @@ index b622498..6ff7277 100644
if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) &&
unlikely(task_ptrace(current) & PT_PTRACED))
send_sig(SIGTRAP, current, 0);
-@@ -211,6 +221,8 @@ static inline void tracehook_report_exec(struct linux_binfmt *fmt,
+@@ -211,6 +221,8 @@ static inline void tracehook_report_exec
*/
static inline void tracehook_report_exit(long *exit_code)
{
@@ -730,7 +763,7 @@ index b622498..6ff7277 100644
ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code);
}
-@@ -254,6 +266,7 @@ static inline int tracehook_prepare_clone(unsigned clone_flags)
+@@ -254,6 +266,7 @@ static inline int tracehook_prepare_clon
static inline void tracehook_finish_clone(struct task_struct *child,
unsigned long clone_flags, int trace)
{
@@ -738,7 +771,7 @@ index b622498..6ff7277 100644
ptrace_init_task(child, (clone_flags & CLONE_PTRACE) || trace);
}
-@@ -280,6 +293,8 @@ static inline void tracehook_report_clone(int trace, struct pt_regs *regs,
+@@ -280,6 +293,8 @@ static inline void tracehook_report_clon
unsigned long clone_flags,
pid_t pid, struct task_struct *child)
{
@@ -747,7 +780,7 @@ index b622498..6ff7277 100644
if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) {
/*
* The child starts up with an immediate SIGSTOP.
-@@ -311,6 +326,9 @@ static inline void tracehook_report_clone_complete(int trace,
+@@ -311,6 +326,9 @@ static inline void tracehook_report_clon
pid_t pid,
struct task_struct *child)
{
@@ -757,7 +790,7 @@ index b622498..6ff7277 100644
if (unlikely(trace))
ptrace_event(0, trace, pid);
}
-@@ -345,6 +363,7 @@ static inline void tracehook_report_vfork_done(struct task_struct *child,
+@@ -345,6 +363,7 @@ static inline void tracehook_report_vfor
*/
static inline void tracehook_prepare_release_task(struct task_struct *task)
{
@@ -765,7 +798,7 @@ index b622498..6ff7277 100644
}
/**
-@@ -359,6 +378,7 @@ static inline void tracehook_prepare_release_task(struct task_struct *task)
+@@ -359,6 +378,7 @@ static inline void tracehook_prepare_rel
static inline void tracehook_finish_release_task(struct task_struct *task)
{
ptrace_release_task(task);
@@ -773,7 +806,7 @@ index b622498..6ff7277 100644
}
/**
-@@ -380,6 +400,8 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info,
+@@ -380,6 +400,8 @@ static inline void tracehook_signal_hand
const struct k_sigaction *ka,
struct pt_regs *regs, int stepping)
{
@@ -782,7 +815,7 @@ index b622498..6ff7277 100644
if (stepping)
ptrace_notify(SIGTRAP);
}
-@@ -400,6 +422,8 @@ static inline int tracehook_consider_ignored_signal(struct task_struct *task,
+@@ -400,6 +422,8 @@ static inline int tracehook_consider_ign
int sig,
void __user *handler)
{
@@ -791,7 +824,7 @@ index b622498..6ff7277 100644
return (task_ptrace(task) & PT_PTRACED) != 0;
}
-@@ -421,6 +445,9 @@ static inline int tracehook_consider_fatal_signal(struct task_struct *task,
+@@ -421,6 +445,9 @@ static inline int tracehook_consider_fat
int sig,
void __user *handler)
{
@@ -801,7 +834,7 @@ index b622498..6ff7277 100644
return (task_ptrace(task) & PT_PTRACED) != 0;
}
-@@ -435,6 +462,8 @@ static inline int tracehook_consider_fatal_signal(struct task_struct *task,
+@@ -435,6 +462,8 @@ static inline int tracehook_consider_fat
*/
static inline int tracehook_force_sigpending(void)
{
@@ -810,7 +843,7 @@ index b622498..6ff7277 100644
return 0;
}
-@@ -464,6 +493,8 @@ static inline int tracehook_get_signal(struct task_struct *task,
+@@ -464,6 +493,8 @@ static inline int tracehook_get_signal(s
siginfo_t *info,
struct k_sigaction *return_ka)
{
@@ -819,7 +852,7 @@ index b622498..6ff7277 100644
return 0;
}
-@@ -491,6 +522,8 @@ static inline int tracehook_get_signal(struct task_struct *task,
+@@ -491,6 +522,8 @@ static inline int tracehook_get_signal(s
*/
static inline int tracehook_notify_jctl(int notify, int why)
{
@@ -828,7 +861,7 @@ index b622498..6ff7277 100644
return notify ?: (current->ptrace & PT_PTRACED) ? why : 0;
}
-@@ -514,6 +547,8 @@ static inline int tracehook_notify_jctl(int notify, int why)
+@@ -514,6 +547,8 @@ static inline int tracehook_notify_jctl(
static inline int tracehook_notify_death(struct task_struct *task,
void **death_cookie, int group_dead)
{
@@ -837,17 +870,28 @@ index b622498..6ff7277 100644
if (task->exit_signal == -1)
return task->ptrace ? SIGCHLD : DEATH_REAP;
-@@ -550,6 +585,9 @@ static inline void tracehook_report_death(struct task_struct *task,
+@@ -550,6 +585,20 @@ static inline void tracehook_report_deat
int signal, void *death_cookie,
int group_dead)
{
++ /*
++ * This barrier ensures that our caller's setting of
++ * @task->exit_state precedes checking @task->utrace_flags here.
++ * 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()
++ * uses tasklist_lock to synchronize enabling the bit with the
++ * actual change to @task->exit_state, but we need this barrier
++ * to be sure we see a flags change made just before our caller
++ * took the tasklist_lock.
++ */
+ smp_mb();
+ if (task_utrace_flags(task) & _UTRACE_DEATH_EVENTS)
+ utrace_report_death(task, death_cookie, group_dead, signal);
}
#ifdef TIF_NOTIFY_RESUME
-@@ -579,10 +617,20 @@ static inline void set_notify_resume(struct task_struct *task)
+@@ -579,10 +628,20 @@ static inline void set_notify_resume(str
* asynchronously, this will be called again before we return to
* user mode.
*
@@ -871,7 +915,7 @@ index b622498..6ff7277 100644
diff --git a/include/linux/utrace.h b/include/linux/utrace.h
new file mode 100644
-index 0000000..f46cc0f
+index ...f877ec6 100644
--- /dev/null
+++ b/include/linux/utrace.h
@@ -0,0 +1,692 @@
@@ -1053,7 +1097,7 @@ index 0000000..f46cc0f
+ * that is developed concurrently with utrace API improvements before they
+ * are merged into the kernel, making LINUX_VERSION_CODE checks unwieldy.
+ */
-+#define UTRACE_API_VERSION 20090302
++#define UTRACE_API_VERSION 20090416
+
+/**
+ * enum utrace_resume_action - engine's choice of action for a traced task
@@ -1569,7 +1613,7 @@ index 0000000..f46cc0f
+#endif /* linux/utrace.h */
diff --git a/include/linux/utrace_struct.h b/include/linux/utrace_struct.h
new file mode 100644
-index 0000000..aba7e09
+index ...aba7e09 100644
--- /dev/null
+++ b/include/linux/utrace_struct.h
@@ -0,0 +1,58 @@
@@ -1632,7 +1676,7 @@ index 0000000..aba7e09
+
+#endif /* linux/utrace_struct.h */
diff --git a/init/Kconfig b/init/Kconfig
-index 6a5c5fe..4b5ab3e 100644
+index 6a5c5fe..4b5ab3e 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1060,6 +1060,15 @@ config STOP_MACHINE
@@ -1652,7 +1696,7 @@ index 6a5c5fe..4b5ab3e 100644
config PREEMPT_NOTIFIERS
diff --git a/kernel/Makefile b/kernel/Makefile
-index e4791b3..7bff724 100644
+index e4791b3..7bff724 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_IKCONFIG) += configs.o
@@ -1664,7 +1708,7 @@ index e4791b3..7bff724 100644
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
-index dc3b98e..f897ef6 100644
+index dc3b98e..f897ef6 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -16,6 +16,7 @@
@@ -1675,7 +1719,7 @@ index dc3b98e..f897ef6 100644
#include <linux/security.h>
#include <linux/signal.h>
#include <linux/audit.h>
-@@ -172,6 +173,14 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
+@@ -172,6 +173,14 @@ bool ptrace_may_access(struct task_struc
return (!err ? true : false);
}
@@ -1715,10 +1759,10 @@ index dc3b98e..f897ef6 100644
*/
diff --git a/kernel/utrace.c b/kernel/utrace.c
new file mode 100644
-index 0000000..115be79
+index ...74b5fc5 100644
--- /dev/null
+++ b/kernel/utrace.c
-@@ -0,0 +1,2348 @@
+@@ -0,0 +1,2357 @@
+/*
+ * utrace infrastructure interface for debugging user processes
+ *
@@ -1935,6 +1979,11 @@ index 0000000..115be79
+ *
+ * UTRACE_ATTACH_MATCH_OPS: Only consider engines matching @ops.
+ * UTRACE_ATTACH_MATCH_DATA: Only consider engines matching @data.
++ *
++ * Calls with neither %UTRACE_ATTACH_MATCH_OPS nor %UTRACE_ATTACH_MATCH_DATA
++ * match the first among any engines attached to @target. That means that
++ * %UTRACE_ATTACH_EXCLUSIVE in such a call fails with -%EEXIST if there
++ * are any engines on @target at all.
+ */
+struct utrace_engine *utrace_attach_task(
+ struct task_struct *target, int flags,
@@ -3167,6 +3216,7 @@ index 0000000..115be79
+ return ops;
+ }
+
++ utrace->reporting = NULL;
+ return NULL;
+}
+
@@ -3178,16 +3228,16 @@ index 0000000..115be79
+#define REPORT(task, utrace, report, event, callback, ...) \
+ do { \
+ start_report(utrace); \
-+ REPORT_CALLBACKS(task, utrace, report, event, callback, \
++ REPORT_CALLBACKS(, task, utrace, report, event, callback, \
+ (report)->action, engine, current, \
+ ## __VA_ARGS__); \
+ finish_report(report, task, utrace); \
+ } while (0)
-+#define REPORT_CALLBACKS(task, utrace, report, event, callback, ...) \
++#define REPORT_CALLBACKS(rev, task, utrace, report, event, callback, ...) \
+ do { \
+ struct utrace_engine *engine; \
+ const struct utrace_engine_ops *ops; \
-+ list_for_each_entry(engine, &utrace->attached, entry) { \
++ list_for_each_entry##rev(engine, &utrace->attached, entry) { \
+ ops = start_callback(utrace, report, engine, task, \
+ event); \
+ if (!ops) \
@@ -3222,9 +3272,9 @@ index 0000000..115be79
+ INIT_REPORT(report);
+
+ start_report(utrace);
-+ REPORT_CALLBACKS(task, utrace, &report, UTRACE_EVENT(SYSCALL_ENTRY),
-+ report_syscall_entry, report.result | report.action,
-+ engine, current, regs);
++ REPORT_CALLBACKS(_reverse, task, utrace, &report,
++ UTRACE_EVENT(SYSCALL_ENTRY), report_syscall_entry,
++ report.result | report.action, engine, current, regs);
+ finish_report(&report, task, utrace);
+
+ if (report.action == UTRACE_STOP &&
@@ -3235,25 +3285,7 @@ index 0000000..115be79
+ */
+ return true;
+
-+ if (unlikely(report.result == UTRACE_SYSCALL_ABORT))
-+ return true;
-+
-+ if (signal_pending(task)) {
-+ /*
-+ * Clear TIF_SIGPENDING if it no longer needs to be set.
-+ * It may have been set as part of quiescence, and won't
-+ * ever have been cleared by another thread. For other
-+ * reports, we can just leave it set and will go through
-+ * utrace_get_signal() to reset things. But here we are
-+ * about to enter a syscall, which might bail out with an
-+ * -ERESTART* error if it's set now.
-+ */
-+ spin_lock_irq(&task->sighand->siglock);
-+ recalc_sigpending();
-+ spin_unlock_irq(&task->sighand->siglock);
-+ }
-+
-+ return false;
++ return report.result == UTRACE_SYSCALL_ABORT;
+}
+
+/*
@@ -3290,7 +3322,7 @@ index 0000000..115be79
+ start_report(utrace);
+ utrace->cloning = child;
+
-+ REPORT_CALLBACKS(task, utrace, &report,
++ REPORT_CALLBACKS(, task, utrace, &report,
+ UTRACE_EVENT(CLONE), report_clone,
+ report.action, engine, task, clone_flags, child);
+
@@ -3440,7 +3472,7 @@ index 0000000..115be79
+ utrace->interrupt = 0;
+ spin_unlock(&utrace->lock);
+
-+ REPORT_CALLBACKS(task, utrace, &report, UTRACE_EVENT(DEATH),
++ REPORT_CALLBACKS(, task, utrace, &report, UTRACE_EVENT(DEATH),
+ report_death, engine, task, group_dead, signal);
+
+ spin_lock(&utrace->lock);
@@ -3484,12 +3516,29 @@ index 0000000..115be79
+ set_tsk_thread_flag(task, TIF_SIGPENDING);
+ break;
+
-+ case UTRACE_SINGLESTEP:
-+ user_enable_single_step(task);
-+ break;
-+
+ case UTRACE_BLOCKSTEP:
-+ user_enable_block_step(task);
++ if (likely(arch_has_block_step())) {
++ user_enable_block_step(task);
++ break;
++ }
++
++ /*
++ * This means some callback is to blame for failing
++ * to check arch_has_block_step() itself. Warn and
++ * then fall through to treat it as SINGLESTEP.
++ */
++ WARN_ON(1);
++
++ case UTRACE_SINGLESTEP:
++ if (likely(arch_has_single_step()))
++ user_enable_single_step(task);
++ else
++ /*
++ * This means some callback is to blame for failing
++ * to check arch_has_single_step() itself. Spew
++ * about it so the loser will fix his module.
++ */
++ WARN_ON(1);
+ break;
+
+ case UTRACE_REPORT:
@@ -3534,11 +3583,15 @@ index 0000000..115be79
+ }
+
+ /*
-+ * If UTRACE_INTERRUPT was just used, we don't bother with a
-+ * report here. We will report and stop in utrace_get_signal().
++ * If UTRACE_INTERRUPT was just used, we don't bother with a report
++ * here. We will report and stop in utrace_get_signal(). In case
++ * of a race with utrace_control(), make sure we don't momentarily
++ * return to user mode because TIF_SIGPENDING was not set yet.
+ */
-+ if (unlikely(utrace->interrupt))
++ if (unlikely(utrace->interrupt)) {
++ set_thread_flag(TIF_SIGPENDING);
+ return;
++ }
+
+ /*
+ * Do a simple reporting pass, with no callback after report_quiesce.
More information about the scm-commits
mailing list