Commit 741a9000 authored by Jinjie Ruan's avatar Jinjie Ruan Committed by Will Deacon
Browse files

arm64/ptrace: Split report_syscall()



The generic syscall entry code has the form:

| syscall_trace_enter()
| {
|	ptrace_report_syscall_entry()
| }
|
| syscall_exit_work()
| {
|	ptrace_report_syscall_exit()
| }

In preparation for moving arm64 over to the generic entry code, split
report_syscall() to two separate enter and exit functions to align
the structure of the arm64 code with syscall_trace_enter() and
syscall_exit_work() from the generic entry code.

No functional changes.

Reviewed-by: default avatarAnshuman Khandual <anshuman.khandual@arm.com>
Reviewed-by: default avatarKevin Brodsky <kevin.brodsky@arm.com>
Suggested-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarJinjie Ruan <ruanjinjie@huawei.com>
Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent e7e7afdc
Loading
Loading
Loading
Loading
+29 −12
Original line number Diff line number Diff line
@@ -2343,9 +2343,10 @@ enum ptrace_syscall_dir {
	PTRACE_SYSCALL_EXIT,
};

static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
static __always_inline unsigned long ptrace_save_reg(struct pt_regs *regs,
						     enum ptrace_syscall_dir dir,
						     int *regno)
{
	int regno;
	unsigned long saved_reg;

	/*
@@ -2364,15 +2365,31 @@ static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
	 * - Syscall stops behave differently to seccomp and pseudo-step traps
	 *   (the latter do not nobble any registers).
	 */
	regno = (is_compat_task() ? 12 : 7);
	saved_reg = regs->regs[regno];
	regs->regs[regno] = dir;
	*regno = (is_compat_task() ? 12 : 7);
	saved_reg = regs->regs[*regno];
	regs->regs[*regno] = dir;

	return saved_reg;
}

static void report_syscall_entry(struct pt_regs *regs)
{
	unsigned long saved_reg;
	int regno;

	if (dir == PTRACE_SYSCALL_ENTER) {
	saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_ENTER, &regno);
	if (ptrace_report_syscall_entry(regs))
		forget_syscall(regs);
	regs->regs[regno] = saved_reg;
	} else if (!test_thread_flag(TIF_SINGLESTEP)) {
}

static void report_syscall_exit(struct pt_regs *regs)
{
	unsigned long saved_reg;
	int regno;

	saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_EXIT, &regno);
	if (!test_thread_flag(TIF_SINGLESTEP)) {
		ptrace_report_syscall_exit(regs, 0);
		regs->regs[regno] = saved_reg;
	} else {
@@ -2392,7 +2409,7 @@ int syscall_trace_enter(struct pt_regs *regs)
	unsigned long flags = read_thread_flags();

	if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
		report_syscall(regs, PTRACE_SYSCALL_ENTER);
		report_syscall_entry(regs);
		if (flags & _TIF_SYSCALL_EMU)
			return NO_SYSCALL;
	}
@@ -2420,7 +2437,7 @@ void syscall_trace_exit(struct pt_regs *regs)
		trace_sys_exit(regs, syscall_get_return_value(current, regs));

	if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))
		report_syscall(regs, PTRACE_SYSCALL_EXIT);
		report_syscall_exit(regs);

	rseq_syscall(regs);
}