summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/ptrace.c
diff options
context:
space:
mode:
authorBreno Leitao <leitao@debian.org>2018-09-20 13:45:06 -0300
committerMichael Ellerman <mpe@ellerman.id.au>2018-10-03 15:40:04 +1000
commit5521eb4bca2db733952f068c37bdf3cd656ad23c (patch)
tree0a9afc5133bff67a13403c75fc7e964a3e99e7ec /arch/powerpc/kernel/ptrace.c
parent16d7c69c898531210d13dbd1eb2053759ff0946d (diff)
powerpc/ptrace: Add support for PTRACE_SYSEMU
This is a patch that adds support for PTRACE_SYSEMU ptrace request in PowerPC architecture. When ptrace(PTRACE_SYSEMU, ...) request is called, it will be handled by the arch independent function ptrace_resume(), which will tag the task with the TIF_SYSCALL_EMU flag. This flag needs to be handled from a platform dependent point of view, which is what this patch does. This patch adds this task's flag as part of the _TIF_SYSCALL_DOTRACE, which is the MACRO that is used to trace syscalls at entrance/exit. Since TIF_SYSCALL_EMU is now part of _TIF_SYSCALL_DOTRACE, if the task has _TIF_SYSCALL_DOTRACE set, it will hit do_syscall_trace_enter() at syscall entrance and do_syscall_trace_leave() at syscall leave. do_syscall_trace_enter() needs to handle the TIF_SYSCALL_EMU flag properly, which will interrupt the syscall executing if TIF_SYSCALL_EMU is set. The output values should not be changed, i.e. the return value (r3) should contain the original syscall argument on exit. With this flag set, the syscall is not executed fundamentally, because do_syscall_trace_enter() is returning -1 which is bigger than NR_syscall, thus, skipping the syscall execution and exiting userspace. Signed-off-by: Breno Leitao <leitao@debian.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r--arch/powerpc/kernel/ptrace.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 9667666eb18e..4e372f54088f 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -2508,6 +2508,7 @@ void ptrace_disable(struct task_struct *child)
{
/* make sure the single step bit is not set. */
user_disable_single_step(child);
+ clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
}
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
@@ -3264,6 +3265,16 @@ long do_syscall_trace_enter(struct pt_regs *regs)
{
user_exit();
+ if (test_thread_flag(TIF_SYSCALL_EMU)) {
+ ptrace_report_syscall(regs);
+ /*
+ * Returning -1 will skip the syscall execution. We want to
+ * avoid clobbering any register also, thus, not 'gotoing'
+ * skip label.
+ */
+ return -1;
+ }
+
/*
* The tracer may decide to abort the syscall, if so tracehook
* will return !0. Note that the tracer may also just change