Commit 4e57a4dd authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Russell King (Oracle)
Browse files

ARM: 9107/1: syscall: always store thread_info->abi_syscall



The system call number is used in a a couple of places, in particular
ptrace, seccomp and /proc/<pid>/syscall.

The last one apparently never worked reliably on ARM for tasks that are
not currently getting traced.

Storing the syscall number in the normal entry path makes it work,
as well as allowing us to see if the current system call is for OABI
compat mode, which is the next thing I want to hook into.

Since the thread_info->syscall field is not just the number any more, it
is now renamed to abi_syscall. In kernels that enable both OABI and EABI,
the upper bits of this field encode 0x900000 (__NR_OABI_SYSCALL_BASE)
for OABI tasks, while normal EABI tasks do not set the upper bits. This
makes it possible to implement the in_oabi_syscall() helper later.

All other users of thread_info->syscall go through the syscall_get_nr()
helper, which in turn filters out the ABI bits.

Note that the ABI information is lost with PTRACE_SET_SYSCALL, so one
cannot set the internal number to a particular version, but this was
already the case. We could change it to let gdb encode the ABI type along
with the syscall in a CONFIG_OABI_COMPAT-enabled kernel, but that itself
would be a (backwards-compatible) ABI change, so I don't do it here.

Acked-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
parent b6e47f3c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -22,7 +22,10 @@ extern const unsigned long sys_call_table[];
static inline int syscall_get_nr(struct task_struct *task,
				 struct pt_regs *regs)
{
	return task_thread_info(task)->syscall;
	if (IS_ENABLED(CONFIG_AEABI) && !IS_ENABLED(CONFIG_OABI_COMPAT))
		return task_thread_info(task)->abi_syscall;

	return task_thread_info(task)->abi_syscall & __NR_SYSCALL_MASK;
}

static inline void syscall_rollback(struct task_struct *task,
+1 −1
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ struct thread_info {
	unsigned long		stack_canary;
#endif
	struct cpu_context_save	cpu_context;	/* cpu context */
	__u32			syscall;	/* syscall number */
	__u32			abi_syscall;	/* ABI type and syscall nr */
	__u8			used_cp[16];	/* thread used copro */
	unsigned long		tp_value[2];	/* TLS registers */
#ifdef CONFIG_CRUNCH
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#define _UAPI__ASM_ARM_UNISTD_H

#define __NR_OABI_SYSCALL_BASE	0x900000
#define __NR_SYSCALL_MASK	0x0fffff

#if defined(__thumb__) || defined(__ARM_EABI__)
#define __NR_SYSCALL_BASE	0
+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ int main(void)
  DEFINE(TI_CPU,		offsetof(struct thread_info, cpu));
  DEFINE(TI_CPU_DOMAIN,		offsetof(struct thread_info, cpu_domain));
  DEFINE(TI_CPU_SAVE,		offsetof(struct thread_info, cpu_context));
  DEFINE(TI_ABI_SYSCALL,	offsetof(struct thread_info, abi_syscall));
  DEFINE(TI_USED_CP,		offsetof(struct thread_info, used_cp));
  DEFINE(TI_TP_VALUE,		offsetof(struct thread_info, tp_value));
  DEFINE(TI_FPSTATE,		offsetof(struct thread_info, fpstate));
+6 −2
Original line number Diff line number Diff line
@@ -226,6 +226,7 @@ ENTRY(vector_swi)
	/* saved_psr and saved_pc are now dead */

	uaccess_disable tbl
	get_thread_info tsk

	adr	tbl, sys_call_table		@ load syscall table pointer

@@ -237,13 +238,17 @@ ENTRY(vector_swi)
	 * get the old ABI syscall table address.
	 */
	bics	r10, r10, #0xff000000
	strne	r10, [tsk, #TI_ABI_SYSCALL]
	streq	scno, [tsk, #TI_ABI_SYSCALL]
	eorne	scno, r10, #__NR_OABI_SYSCALL_BASE
	ldrne	tbl, =sys_oabi_call_table
#elif !defined(CONFIG_AEABI)
	bic	scno, scno, #0xff000000		@ mask off SWI op-code
	str	scno, [tsk, #TI_ABI_SYSCALL]
	eor	scno, scno, #__NR_SYSCALL_BASE	@ check OS number
#else
	str	scno, [tsk, #TI_ABI_SYSCALL]
#endif
	get_thread_info tsk
	/*
	 * Reload the registers that may have been corrupted on entry to
	 * the syscall assembly (by tracing or context tracking.)
@@ -288,7 +293,6 @@ ENDPROC(vector_swi)
	 * context switches, and waiting for our parent to respond.
	 */
__sys_trace:
	mov	r1, scno
	add	r0, sp, #S_OFF
	bl	syscall_trace_enter
	mov	scno, r0
Loading