Turn context->sysemu into PTRACE_O_SYSEMU. This flag is not visible to user space, and it has no effect after the tracee was stopped.
IOW, PTRACE_SETOPTIONS always clear PTRACE_O_SYSEMU but this doesn't matter, all we need it should be correct after ptrace_resume() wakes up the tracee. --- kernel/ptrace.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) --- PU/kernel/ptrace.c~106_KILL_CONTEXT_SYSEMU 2009-10-20 15:58:19.000000000 +0200 +++ PU/kernel/ptrace.c 2009-10-20 17:22:27.000000000 +0200 @@ -27,8 +27,6 @@ struct ptrace_context { int options; - bool sysemu; // XXX: will die soon - int signr; siginfo_t *siginfo; @@ -38,6 +36,8 @@ struct ptrace_context { enum utrace_resume_action resume; }; +#define PTRACE_O_SYSEMU 0x100 + #define PTRACE_EVENT_SYSCALL_ENTRY (1 << 16) #define PTRACE_EVENT_SYSCALL_EXIT (2 << 16) #define PTRACE_EVENT_SIGTRAP (3 << 16) @@ -252,7 +252,7 @@ static u32 ptrace_report_syscall_entry(u set_syscall_code(context, PTRACE_EVENT_SYSCALL_ENTRY); - if (unlikely(context->sysemu)) { + if (unlikely(context->options & PTRACE_O_SYSEMU)) { if (test_thread_flag(TIF_SINGLESTEP)) user_disable_single_step(task); return UTRACE_SYSCALL_ABORT | UTRACE_REPORT; @@ -851,8 +851,9 @@ int ptrace_writedata(struct task_struct static int ptrace_set_options(struct utrace_engine *engine, struct task_struct *child, long data) { - __ptrace_set_options(child, engine, data & PTRACE_O_MASK); + BUILD_BUG_ON(PTRACE_O_MASK & PTRACE_O_SYSEMU); + __ptrace_set_options(child, engine, data & PTRACE_O_MASK); return (data & ~PTRACE_O_MASK) ? -EINVAL : 0; } @@ -1026,7 +1027,7 @@ static int ptrace_resume(struct utrace_e if (!valid_signal(data)) return -EIO; - context->sysemu = false; + context->options &= ~PTRACE_O_SYSEMU; events = engine->flags & ~UTRACE_EVENT_SYSCALL; action = UTRACE_RESUME; @@ -1053,7 +1054,7 @@ static int ptrace_resume(struct utrace_e return -EIO; action = UTRACE_SINGLESTEP; case PTRACE_SYSEMU: - context->sysemu = true; + context->options |= PTRACE_O_SYSEMU; events |= UTRACE_EVENT(SYSCALL_ENTRY); break; #endif