Preparation, no functional changes. - change ptrace_report_signal()->resume_signal() to clear ctx->signr, not only ctx->siginfo. This allows us to overload ctx->signr.
IOW, with this patch ctx->signr != 0 is only possible when a tracee is stopped with the valid ctx->siginfo after reporting the signal. - move the "default" case out of "switch()". This allows to re-use this code path to inject SIGTRAP's. --- kernel/ptrace.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) --- PU/kernel/ptrace.c~126_REPORT_SIGNAL_MOVE_DEFAULT 2009-11-01 22:48:24.000000000 +0100 +++ PU/kernel/ptrace.c 2009-11-02 00:31:30.000000000 +0100 @@ -440,9 +440,15 @@ static u32 ptrace_report_exec(enum utrac } static enum utrace_signal_action resume_signal(struct task_struct *task, - int signr, siginfo_t *info, + struct ptrace_context *ctx, struct k_sigaction *return_ka) { + siginfo_t *info = ctx->siginfo; + int signr = ctx->signr; + + ctx->siginfo = NULL; + ctx->signr = 0; + /* Did the debugger cancel the sig? */ if (!signr) return UTRACE_SIGNAL_IGN; @@ -505,25 +511,26 @@ static u32 ptrace_report_signal(u32 acti if (WARN_ON(ctx->siginfo != info)) return resume | UTRACE_SIGNAL_IGN; - ctx->siginfo = NULL; - return resume | resume_signal(task, ctx->signr, - info, return_ka); + return resume | resume_signal(task, ctx, return_ka); + default: - WARN_ON(ctx->siginfo); - ctx->siginfo = info; - /* - * ctx->siginfo points to the caller's stack. - * Make sure the subsequent UTRACE_SIGNAL_REPORT clears - * ->siginfo before return from get_signal_to_deliver(). - */ - utrace_control(task, engine, UTRACE_INTERRUPT); + break; + } - ctx->stop_code = (PTRACE_EVENT_SIGNAL << 8) | info->si_signo; - ctx->signr = info->si_signo; + WARN_ON(ctx->siginfo); + ctx->siginfo = info; + /* + * ctx->siginfo points to the caller's stack. + * Make sure the subsequent UTRACE_SIGNAL_REPORT clears + * ->siginfo before return from get_signal_to_deliver(). + */ + utrace_control(task, engine, UTRACE_INTERRUPT); - return UTRACE_STOP | UTRACE_SIGNAL_IGN; - } + ctx->signr = info->si_signo; + ctx->stop_code = (PTRACE_EVENT_SIGNAL << 8) | ctx->signr; + + return UTRACE_STOP | UTRACE_SIGNAL_IGN; } static u32 ptrace_report_quiesce(u32 action,