summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/syscall.c
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2017-05-31 16:19:48 +0100
committerRalf Baechle <ralf@linux-mips.org>2017-06-28 12:22:40 +0200
commit49955d84cd9ccdca5a16a495e448e1a06fad9e49 (patch)
tree6079d40979a3343c3d93e69e665e7f06176f8676 /arch/mips/kernel/syscall.c
parent2ec420b26f7b6ff332393f0bb5a7d245f7ad87f0 (diff)
downloadlinux-0-day-49955d84cd9ccdca5a16a495e448e1a06fad9e49.tar.gz
linux-0-day-49955d84cd9ccdca5a16a495e448e1a06fad9e49.tar.xz
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.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 95e1b300ac0d0..3e5d82e744ac1 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) {