@@ -75,6 +75,7 @@ struct thread_info {
* TIF_SYSCALL_TRACE - syscall trace active
* TIF_SYSCALL_TRACEPOINT - syscall tracepoint for ftrace
* TIF_SYSCALL_AUDIT - syscall auditing
+ * TIF_SYSCALL_EMU - syscall emulation active
* TIF_SECOMP - syscall secure computing
* TIF_SIGPENDING - signal pending
* TIF_NEED_RESCHED - rescheduling necessary
@@ -91,6 +92,7 @@ struct thread_info {
#define TIF_SYSCALL_AUDIT 9
#define TIF_SYSCALL_TRACEPOINT 10
#define TIF_SECCOMP 11
+#define TIF_SYSCALL_EMU 12
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FREEZE 19
#define TIF_RESTORE_SIGMASK 20
@@ -106,6 +108,7 @@ struct thread_info {
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
+#define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU)
#define _TIF_UPROBE (1 << TIF_UPROBE)
#define _TIF_32BIT (1 << TIF_32BIT)
@@ -115,7 +118,7 @@ struct thread_info {
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
- _TIF_NOHZ)
+ _TIF_NOHZ | _TIF_SYSCALL_EMU)
#endif /* __KERNEL__ */
#endif /* __ASM_THREAD_INFO_H */
@@ -23,6 +23,8 @@
#include <asm/hwcap.h>
+#define PTRACE_SYSEMU 31
+#define PTRACE_SYSEMU_SINGLESTEP 32
/*
* PSR bits
@@ -165,6 +165,9 @@ void ptrace_disable(struct task_struct *child)
* is likely to cause regressions on obscure architectures.
*/
user_disable_single_step(child);
+#ifdef TIF_SYSCALL_EMU
+ clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
+#endif
}
#ifdef CONFIG_HAVE_HW_BREAKPOINT
@@ -1351,6 +1354,11 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+ if (test_thread_flag(TIF_SYSCALL_EMU)) {
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+ return -1;
+ }
+
/* Do the secure computing after ptrace; failures should be fast. */
if (secure_computing(NULL) == -1)
return -1;
@@ -1373,6 +1381,15 @@ asmlinkage void syscall_trace_exit(struct pt_regs *regs)
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
+
+ /*
+ * We only get here because of TIF_SINGLESTEP,
+ * for PTRACE_SYSEMU_SINGLESTEP, we already reported
+ * the syscall instruction in syscall_trace_enter().
+ */
+ if (test_thread_flag(TIF_SINGLESTEP) &&
+ !test_thread_flag(TIF_SYSCALL_EMU))
+ tracehook_report_syscall_exit(regs, 1);
}
/*