arm64: remove sigreturn wrappers
authorMark Rutland <mark.rutland@arm.com>
Wed, 11 Jul 2018 13:56:41 +0000 (14:56 +0100)
committerWill Deacon <will.deacon@arm.com>
Thu, 12 Jul 2018 13:40:39 +0000 (14:40 +0100)
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 <mark.rutland@arm.com>
Tentatively-reviewed-by: Dave Martin <dave.martin@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
arch/arm64/include/asm/unistd32.h
arch/arm64/kernel/entry.S
arch/arm64/kernel/entry32.S
arch/arm64/kernel/signal.c
arch/arm64/kernel/signal32.c
arch/arm64/kernel/sys.c
arch/arm64/kernel/sys32.c

index 0fdc7ef8a776cc92ada6310ccccaf53bfae40db8..023d64af833908d24dd6e2499bb5c5d351123cdd 100644 (file)
@@ -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
@@ -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
index 1eda9e1a1f4a5820b557717cb804fda6022a9fec..201809537343130a8014fd6221231df57d0bbbd1 100644 (file)
@@ -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:
index f332d5d1f6b40c1b5382301d103fe3ed588ea4c1..f9461696dde4caaefed46dd3fd201bc096f36b6a 100644 (file)
  * 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
index 5a8df96dc4ab7fa2f0da6b743d0c6dbda39a8a02..b6f3c3d76901a143ec1f0e05dde59195efd3822e 100644 (file)
@@ -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 */
index fca761be18c8f1aaeda43ff6c61281fd78bf7ba7..9aac1253e0a6a80e36bc894b9c8473ae07c2511b 100644 (file)
@@ -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 */
@@ -315,8 +316,9 @@ badframe:
        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 */
index 72981bae10ebaa41d9a9b26743121640ceb40acb..31045f3fed924a009dcbc5d72bae9da49f163990 100644 (file)
@@ -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
index a40b1343b819f86bdf4a0e80f143a12425f8fd6b..1ef103c9541065dde35d8255e467aca7bf7c4712 100644 (file)
@@ -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);