Skip to content

Commit

Permalink
arm64: remove sigreturn wrappers
Browse files Browse the repository at this point in the history
The arm64 sigreturn* syscall handlers are non-standard. Rather than
taking a number of user parameters in registers as per the AAPCS,
they expect the pt_regs as their sole argument.

To make this work, we override the syscall definitions to invoke
wrappers written in assembly, which mov the SP into x0, and branch to
their respective C functions.

On other architectures (such as x86), the sigreturn* functions take no
argument and instead use current_pt_regs() to acquire the user
registers. This requires less boilerplate code, and allows for other
features such as interposing C code in this path.

This patch takes the same approach for arm64.

Signed-off-by: Mark Rutland <[email protected]>
Tentatively-reviewed-by: Dave Martin <[email protected]>
Reviewed-by: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
  • Loading branch information
Mark Rutland authored and wildea01 committed Jul 12, 2018
1 parent f9209e2 commit 3085e16
Show file tree
Hide file tree
Showing 7 changed files with 11 additions and 27 deletions.
4 changes: 2 additions & 2 deletions arch/arm64/include/asm/unistd32.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ __SYSCALL(117, sys_ni_syscall)
#define __NR_fsync 118
__SYSCALL(__NR_fsync, sys_fsync)
#define __NR_sigreturn 119
__SYSCALL(__NR_sigreturn, compat_sys_sigreturn_wrapper)
__SYSCALL(__NR_sigreturn, compat_sys_sigreturn)
#define __NR_clone 120
__SYSCALL(__NR_clone, sys_clone)
#define __NR_setdomainname 121
Expand Down Expand Up @@ -368,7 +368,7 @@ __SYSCALL(__NR_getresgid, sys_getresgid16)
#define __NR_prctl 172
__SYSCALL(__NR_prctl, sys_prctl)
#define __NR_rt_sigreturn 173
__SYSCALL(__NR_rt_sigreturn, compat_sys_rt_sigreturn_wrapper)
__SYSCALL(__NR_rt_sigreturn, compat_sys_rt_sigreturn)
#define __NR_rt_sigaction 174
__SYSCALL(__NR_rt_sigaction, compat_sys_rt_sigaction)
#define __NR_rt_sigprocmask 175
Expand Down
8 changes: 0 additions & 8 deletions arch/arm64/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -1139,14 +1139,6 @@ __entry_tramp_data_start:
#endif /* CONFIG_RANDOMIZE_BASE */
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */

/*
* Special system call wrappers.
*/
ENTRY(sys_rt_sigreturn_wrapper)
mov x0, sp
b sys_rt_sigreturn
ENDPROC(sys_rt_sigreturn_wrapper)

/*
* Register switch for AArch64. The callee-saved registers need to be saved
* and restored. On entry:
Expand Down
10 changes: 0 additions & 10 deletions arch/arm64/kernel/entry32.S
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@
* System call wrappers for the AArch32 compatibility layer.
*/

ENTRY(compat_sys_sigreturn_wrapper)
mov x0, sp
b compat_sys_sigreturn
ENDPROC(compat_sys_sigreturn_wrapper)

ENTRY(compat_sys_rt_sigreturn_wrapper)
mov x0, sp
b compat_sys_rt_sigreturn
ENDPROC(compat_sys_rt_sigreturn_wrapper)

ENTRY(compat_sys_statfs64_wrapper)
mov w3, #84
cmp w1, #88
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,9 @@ static int restore_sigframe(struct pt_regs *regs,
return err;
}

asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
asmlinkage long sys_rt_sigreturn(void)
{
struct pt_regs *regs = current_pt_regs();
struct rt_sigframe __user *frame;

/* Always make any pending restarted system calls return -EINTR */
Expand Down
6 changes: 4 additions & 2 deletions arch/arm64/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,9 @@ static int compat_restore_sigframe(struct pt_regs *regs,
return err;
}

asmlinkage int compat_sys_sigreturn(struct pt_regs *regs)
asmlinkage int compat_sys_sigreturn(void)
{
struct pt_regs *regs = current_pt_regs();
struct compat_sigframe __user *frame;

/* Always make any pending restarted system calls return -EINTR */
Expand Down Expand Up @@ -315,8 +316,9 @@ asmlinkage int compat_sys_sigreturn(struct pt_regs *regs)
return 0;
}

asmlinkage int compat_sys_rt_sigreturn(struct pt_regs *regs)
asmlinkage int compat_sys_rt_sigreturn(void)
{
struct pt_regs *regs = current_pt_regs();
struct compat_rt_sigframe __user *frame;

/* Always make any pending restarted system calls return -EINTR */
Expand Down
3 changes: 1 addition & 2 deletions arch/arm64/kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
/*
* Wrappers to pass the pt_regs argument.
*/
asmlinkage long sys_rt_sigreturn_wrapper(void);
#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
asmlinkage long sys_rt_sigreturn(void);
#define sys_personality sys_arm64_personality

#undef __SYSCALL
Expand Down
4 changes: 2 additions & 2 deletions arch/arm64/kernel/sys32.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
#include <linux/compiler.h>
#include <linux/syscalls.h>

asmlinkage long compat_sys_sigreturn_wrapper(void);
asmlinkage long compat_sys_rt_sigreturn_wrapper(void);
asmlinkage long compat_sys_sigreturn(void);
asmlinkage long compat_sys_rt_sigreturn(void);
asmlinkage long compat_sys_statfs64_wrapper(void);
asmlinkage long compat_sys_fstatfs64_wrapper(void);
asmlinkage long compat_sys_pread64_wrapper(void);
Expand Down

0 comments on commit 3085e16

Please sign in to comment.