Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

James Hogan and committed by
Ralf Baechle
49955d84 2ec420b2

+10 -4
+1 -1
arch/mips/kernel/scall32-o32.S
··· 371 371 PTR sys_writev 372 372 PTR sys_cacheflush 373 373 PTR sys_cachectl 374 - PTR sys_sysmips 374 + PTR __sys_sysmips 375 375 PTR sys_ni_syscall /* 4150 */ 376 376 PTR sys_getsid 377 377 PTR sys_fdatasync
+1 -1
arch/mips/kernel/scall64-64.S
··· 311 311 PTR sys_sched_getaffinity 312 312 PTR sys_cacheflush 313 313 PTR sys_cachectl 314 - PTR sys_sysmips 314 + PTR __sys_sysmips 315 315 PTR sys_io_setup /* 5200 */ 316 316 PTR sys_io_destroy 317 317 PTR sys_io_getevents
+1 -1
arch/mips/kernel/scall64-n32.S
··· 302 302 PTR compat_sys_sched_getaffinity 303 303 PTR sys_cacheflush 304 304 PTR sys_cachectl 305 - PTR sys_sysmips 305 + PTR __sys_sysmips 306 306 PTR compat_sys_io_setup /* 6200 */ 307 307 PTR sys_io_destroy 308 308 PTR compat_sys_io_getevents
+1 -1
arch/mips/kernel/scall64-o32.S
··· 371 371 PTR compat_sys_writev 372 372 PTR sys_cacheflush 373 373 PTR sys_cachectl 374 - PTR sys_sysmips 374 + PTR __sys_sysmips 375 375 PTR sys_ni_syscall /* 4150 */ 376 376 PTR sys_getsid 377 377 PTR sys_fdatasync
+6
arch/mips/kernel/syscall.c
··· 192 192 unreachable(); 193 193 } 194 194 195 + /* 196 + * mips_atomic_set() normally returns directly via syscall_exit potentially 197 + * clobbering static registers, so be sure to preserve them. 198 + */ 199 + save_static_function(sys_sysmips); 200 + 195 201 SYSCALL_DEFINE3(sysmips, long, cmd, long, arg1, long, arg2) 196 202 { 197 203 switch (cmd) {