Commit 3aa99d74 authored by Will Deacon's avatar Will Deacon
Browse files

Merge branch 'for-next/entry' into for-next/core

* for-next/entry:
  arm64/ptrace: Return early for ptrace_report_syscall_entry() error
  arm64/ptrace: Split report_syscall()
  arm64: Remove unused _TIF_WORK_MASK
  arm64: Avoid memcpy() for syscall_get_arguments()
  syscall.h: Remove unused SYSCALL_MAX_ARGS
parents c2581836 a3386301
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -92,8 +92,6 @@ static inline void syscall_set_nr(struct task_struct *task,
		(nr & __NR_SYSCALL_MASK);
}

#define SYSCALL_MAX_ARGS 7

static inline void syscall_get_arguments(struct task_struct *task,
					 struct pt_regs *regs,
					 unsigned long *args)
+12 −6
Original line number Diff line number Diff line
@@ -77,23 +77,29 @@ static inline void syscall_set_nr(struct task_struct *task,
	}
}

#define SYSCALL_MAX_ARGS 6

static inline void syscall_get_arguments(struct task_struct *task,
					 struct pt_regs *regs,
					 unsigned long *args)
{
	args[0] = regs->orig_x0;
	args++;

	memcpy(args, &regs->regs[1], 5 * sizeof(args[0]));
	args[1] = regs->regs[1];
	args[2] = regs->regs[2];
	args[3] = regs->regs[3];
	args[4] = regs->regs[4];
	args[5] = regs->regs[5];
}

static inline void syscall_set_arguments(struct task_struct *task,
					 struct pt_regs *regs,
					 const unsigned long *args)
{
	memcpy(&regs->regs[0], args, 6 * sizeof(args[0]));
	regs->regs[0] = args[0];
	regs->regs[1] = args[1];
	regs->regs[2] = args[2];
	regs->regs[3] = args[3];
	regs->regs[4] = args[4];
	regs->regs[5] = args[5];

	/*
	 * Also copy the first argument into orig_x0
	 * so that syscall_get_arguments() would return it
+0 −6
Original line number Diff line number Diff line
@@ -106,12 +106,6 @@ void arch_setup_new_exec(void);
#define _TIF_NOTIFY_SIGNAL	(1 << TIF_NOTIFY_SIGNAL)
#define _TIF_TSC_SIGSEGV	(1 << TIF_TSC_SIGSEGV)

#define _TIF_WORK_MASK		(_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY | \
				 _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
				 _TIF_UPROBE | _TIF_MTE_ASYNC_FAULT | \
				 _TIF_NOTIFY_SIGNAL | _TIF_SIGPENDING | \
				 _TIF_PATCH_PENDING)

#define _TIF_SYSCALL_WORK	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
				 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
				 _TIF_SYSCALL_EMU)
+34 −13
Original line number Diff line number Diff line
@@ -2346,9 +2346,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;

	/*
@@ -2367,15 +2368,34 @@ 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 int report_syscall_entry(struct pt_regs *regs)
{
	unsigned long saved_reg;
	int regno, ret;

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

	return ret;
}

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 {
@@ -2393,10 +2413,11 @@ static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
int syscall_trace_enter(struct pt_regs *regs)
{
	unsigned long flags = read_thread_flags();
	int ret;

	if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
		report_syscall(regs, PTRACE_SYSCALL_ENTER);
		if (flags & _TIF_SYSCALL_EMU)
		ret = report_syscall_entry(regs);
		if (ret || (flags & _TIF_SYSCALL_EMU))
			return NO_SYSCALL;
	}

@@ -2423,7 +2444,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);
}
+0 −1
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ static inline void syscall_set_return_value(struct task_struct *task,
	regs->areg[2] = (long) error ? error : val;
}

#define SYSCALL_MAX_ARGS 6
#define XTENSA_SYSCALL_ARGUMENT_REGS {6, 3, 4, 5, 8, 9}

static inline void syscall_get_arguments(struct task_struct *task,