diff options
author | James Hogan <james.hogan@imgtec.com> | 2017-05-31 16:19:48 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2017-06-28 12:22:40 +0200 |
commit | 49955d84cd9ccdca5a16a495e448e1a06fad9e49 (patch) | |
tree | 6079d40979a3343c3d93e69e665e7f06176f8676 /arch/mips/kernel/syscall.c | |
parent | 2ec420b26f7b6ff332393f0bb5a7d245f7ad87f0 (diff) | |
download | linux-49955d84cd9ccdca5a16a495e448e1a06fad9e49.tar.gz |
MIPS: Save static registers before sysmips
The MIPS sysmips system call handler may return directly from the
MIPS_ATOMIC_SET case (mips_atomic_set()) to syscall_exit. This path
restores the static (callee saved) registers, however they won't have
been saved on entry to the system call.
Use the save_static_function() macro to create a __sys_sysmips wrapper
function which saves the static registers before calling sys_sysmips, so
that the correct static register state is restored by syscall_exit.
Fixes: f1e39a4a616c ("MIPS: Rewrite sysmips(MIPS_ATOMIC_SET, ...) in C with inline assembler")
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: stable@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/16149/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/syscall.c')
-rw-r--r-- | arch/mips/kernel/syscall.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 95e1b300ac0d..3e5d82e744ac 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -192,6 +192,12 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) unreachable(); } +/* + * mips_atomic_set() normally returns directly via syscall_exit potentially + * clobbering static registers, so be sure to preserve them. + */ +save_static_function(sys_sysmips); + SYSCALL_DEFINE3(sysmips, long, cmd, long, arg1, long, arg2) { switch (cmd) { |