11da177e4SLinus Torvalds/* 21da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 31da177e4SLinus Torvalds * License. See the file "COPYING" in the main directory of this archive 41da177e4SLinus Torvalds * for more details. 51da177e4SLinus Torvalds * 6192ef366SRalf Baechle * Copyright (C) 1995-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org> 71da177e4SLinus Torvalds * Copyright (C) 2001 MIPS Technologies, Inc. 81da177e4SLinus Torvalds * Copyright (C) 2004 Thiemo Seufer 986bdb277SMarkos Chandras * Copyright (C) 2014 Imagination Technologies Ltd. 101da177e4SLinus Torvalds */ 111da177e4SLinus Torvalds#include <linux/errno.h> 121da177e4SLinus Torvalds#include <asm/asm.h> 131da177e4SLinus Torvalds#include <asm/asmmacro.h> 14192ef366SRalf Baechle#include <asm/irqflags.h> 151da177e4SLinus Torvalds#include <asm/mipsregs.h> 161da177e4SLinus Torvalds#include <asm/regdef.h> 171da177e4SLinus Torvalds#include <asm/stackframe.h> 181da177e4SLinus Torvalds#include <asm/isadep.h> 191da177e4SLinus Torvalds#include <asm/sysmips.h> 201da177e4SLinus Torvalds#include <asm/thread_info.h> 211da177e4SLinus Torvalds#include <asm/unistd.h> 22048eb582SSam Ravnborg#include <asm/asm-offsets.h> 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds .align 5 251da177e4SLinus TorvaldsNESTED(handle_sys, PT_SIZE, sp) 261da177e4SLinus Torvalds .set noat 271da177e4SLinus Torvalds SAVE_SOME 28eae6c0daSAtsushi Nemoto TRACE_IRQS_ON_RELOAD 291da177e4SLinus Torvalds STI 301da177e4SLinus Torvalds .set at 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds lw t1, PT_EPC(sp) # skip syscall on return 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds addiu t1, 4 # skip to next instruction 351da177e4SLinus Torvalds sw t1, PT_EPC(sp) 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds sw a3, PT_R26(sp) # save a3 for syscall restarting 381da177e4SLinus Torvalds 3946e12c07SRalf Baechle /* 4046e12c07SRalf Baechle * More than four arguments. Try to deal with it by copying the 4146e12c07SRalf Baechle * stack arguments from the user stack to the kernel stack. 4246e12c07SRalf Baechle * This Sucks (TM). 4346e12c07SRalf Baechle */ 4446e12c07SRalf Baechle lw t0, PT_R29(sp) # get old user stack pointer 4546e12c07SRalf Baechle 4646e12c07SRalf Baechle /* 4746e12c07SRalf Baechle * We intentionally keep the kernel stack a little below the top of 4846e12c07SRalf Baechle * userspace so we don't have to do a slower byte accurate check here. 4946e12c07SRalf Baechle */ 5046e12c07SRalf Baechle addu t4, t0, 32 5104324f44SThomas Bogendoerfer bltz t4, bad_stack # -> sp is bad 5246e12c07SRalf Baechle 5346e12c07SRalf Baechle /* 5446e12c07SRalf Baechle * Ok, copy the args from the luser stack to the kernel stack. 5546e12c07SRalf Baechle */ 5646e12c07SRalf Baechle 5746e12c07SRalf Baechle .set push 5846e12c07SRalf Baechle .set noreorder 5946e12c07SRalf Baechle .set nomacro 6046e12c07SRalf Baechle 617928eb03SRalf Baechleload_a4: user_lw(t5, 16(t0)) # argument #5 from usp 627928eb03SRalf Baechleload_a5: user_lw(t6, 20(t0)) # argument #6 from usp 637928eb03SRalf Baechleload_a6: user_lw(t7, 24(t0)) # argument #7 from usp 647928eb03SRalf Baechleload_a7: user_lw(t8, 28(t0)) # argument #8 from usp 657928eb03SRalf Baechleloads_done: 6646e12c07SRalf Baechle 6746e12c07SRalf Baechle sw t5, 16(sp) # argument #5 to ksp 6846e12c07SRalf Baechle sw t6, 20(sp) # argument #6 to ksp 6946e12c07SRalf Baechle sw t7, 24(sp) # argument #7 to ksp 7046e12c07SRalf Baechle sw t8, 28(sp) # argument #8 to ksp 7146e12c07SRalf Baechle .set pop 7246e12c07SRalf Baechle 7346e12c07SRalf Baechle .section __ex_table,"a" 74fa62f39dSThomas Bogendoerfer PTR_WD load_a4, bad_stack_a4 75fa62f39dSThomas Bogendoerfer PTR_WD load_a5, bad_stack_a5 76fa62f39dSThomas Bogendoerfer PTR_WD load_a6, bad_stack_a6 77fa62f39dSThomas Bogendoerfer PTR_WD load_a7, bad_stack_a7 7846e12c07SRalf Baechle .previous 7946e12c07SRalf Baechle 80*4370b673SJiaxun Yang /* 81*4370b673SJiaxun Yang * syscall number is in v0 unless we called syscall(__NR_###) 82*4370b673SJiaxun Yang * where the real syscall number is in a0 83*4370b673SJiaxun Yang */ 84*4370b673SJiaxun Yang subu t2, v0, __NR_O32_Linux 85*4370b673SJiaxun Yang bnez t2, 1f /* __NR_syscall at offset 0 */ 86*4370b673SJiaxun Yang LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number 87*4370b673SJiaxun Yang b 2f 88*4370b673SJiaxun Yang1: 89*4370b673SJiaxun Yang LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number 90*4370b673SJiaxun Yang2: 91*4370b673SJiaxun Yang 921da177e4SLinus Torvalds lw t0, TI_FLAGS($28) # syscall tracing enabled? 93e7f3b48aSRalf Baechle li t1, _TIF_WORK_SYSCALL_ENTRY 941da177e4SLinus Torvalds and t0, t1 951da177e4SLinus Torvalds bnez t0, syscall_trace_entry # -> yes 96d218af78SMarkos Chandrassyscall_common: 97a400bed6SMatt Redfearn subu v0, v0, __NR_O32_Linux # check syscall number 98be856439SFiroz Khan sltiu t0, v0, __NR_O32_Linux_syscalls 99d218af78SMarkos Chandras beqz t0, illegal_syscall 100d218af78SMarkos Chandras 101d218af78SMarkos Chandras sll t0, v0, 2 102d218af78SMarkos Chandras la t1, sys_call_table 103d218af78SMarkos Chandras addu t1, t0 104d218af78SMarkos Chandras lw t2, (t1) # syscall routine 105d218af78SMarkos Chandras 106d218af78SMarkos Chandras beqz t2, illegal_syscall 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds jalr t2 # Do The Real Thing (TM) 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds li t0, -EMAXERRNO - 1 # error? 1111da177e4SLinus Torvalds sltu t0, t0, v0 1121da177e4SLinus Torvalds sw t0, PT_R7(sp) # set error flag 1131da177e4SLinus Torvalds beqz t0, 1f 1141da177e4SLinus Torvalds 1158f5a00ebSAl Viro lw t1, PT_R2(sp) # syscall number 1161da177e4SLinus Torvalds negu v0 # error 1178f5a00ebSAl Viro sw t1, PT_R0(sp) # save it for syscall restarting 1181da177e4SLinus Torvalds1: sw v0, PT_R2(sp) # result 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvaldso32_syscall_exit: 12102f884edSAl Viro j syscall_exit_partial 1221da177e4SLinus Torvalds 1231da177e4SLinus Torvalds/* ------------------------------------------------------------------------ */ 1241da177e4SLinus Torvalds 1251da177e4SLinus Torvaldssyscall_trace_entry: 1261da177e4SLinus Torvalds SAVE_STATIC 1271da177e4SLinus Torvalds move a0, sp 1284c21b8fdSMarkos Chandras 129*4370b673SJiaxun Yang jal syscall_trace_enter 1301da177e4SLinus Torvalds 131d218af78SMarkos Chandras bltz v0, 1f # seccomp failed? Skip syscall 1329d37c405SMarkos Chandras 13304a7052cSRalf Baechle RESTORE_STATIC 134a400bed6SMatt Redfearn lw v0, PT_R2(sp) # Restore syscall (maybe modified) 1351da177e4SLinus Torvalds lw a0, PT_R4(sp) # Restore argument registers 1361da177e4SLinus Torvalds lw a1, PT_R5(sp) 1371da177e4SLinus Torvalds lw a2, PT_R6(sp) 1381da177e4SLinus Torvalds lw a3, PT_R7(sp) 139d218af78SMarkos Chandras j syscall_common 1401da177e4SLinus Torvalds 141d218af78SMarkos Chandras1: j syscall_exit 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds/* ------------------------------------------------------------------------ */ 1441da177e4SLinus Torvalds 1451da177e4SLinus Torvalds /* 1467928eb03SRalf Baechle * Our open-coded access area sanity test for the stack pointer 1477928eb03SRalf Baechle * failed. We probably should handle this case a bit more drastic. 1481da177e4SLinus Torvalds */ 1491da177e4SLinus Torvaldsbad_stack: 1505b89c004SAl Viro li v0, EFAULT 1511da177e4SLinus Torvalds sw v0, PT_R2(sp) 1521da177e4SLinus Torvalds li t0, 1 # set error flag 1531da177e4SLinus Torvalds sw t0, PT_R7(sp) 1541da177e4SLinus Torvalds j o32_syscall_exit 1551da177e4SLinus Torvalds 1567928eb03SRalf Baechlebad_stack_a4: 1577928eb03SRalf Baechle li t5, 0 1587928eb03SRalf Baechle b load_a5 1597928eb03SRalf Baechle 1607928eb03SRalf Baechlebad_stack_a5: 1617928eb03SRalf Baechle li t6, 0 1627928eb03SRalf Baechle b load_a6 1637928eb03SRalf Baechle 1647928eb03SRalf Baechlebad_stack_a6: 1657928eb03SRalf Baechle li t7, 0 1667928eb03SRalf Baechle b load_a7 1677928eb03SRalf Baechle 1687928eb03SRalf Baechlebad_stack_a7: 1697928eb03SRalf Baechle li t8, 0 1707928eb03SRalf Baechle b loads_done 1717928eb03SRalf Baechle 1721da177e4SLinus Torvalds /* 1731da177e4SLinus Torvalds * The system call does not exist in this kernel 1741da177e4SLinus Torvalds */ 1751da177e4SLinus Torvaldsillegal_syscall: 176bda8229bSAtsushi Nemoto li v0, ENOSYS # error 1771da177e4SLinus Torvalds sw v0, PT_R2(sp) 1781da177e4SLinus Torvalds li t0, 1 # set error flag 1791da177e4SLinus Torvalds sw t0, PT_R7(sp) 1801da177e4SLinus Torvalds j o32_syscall_exit 1811da177e4SLinus Torvalds END(handle_sys) 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds LEAF(sys_syscall) 1841da177e4SLinus Torvalds subu t0, a0, __NR_O32_Linux # check syscall number 185be856439SFiroz Khan sltiu v0, t0, __NR_O32_Linux_syscalls 186e807f957SVlad Malov beqz t0, einval # do not recurse 18746e12c07SRalf Baechle sll t1, t0, 2 1881da177e4SLinus Torvalds beqz v0, einval 1891da177e4SLinus Torvalds lw t2, sys_call_table(t1) # syscall routine 1901da177e4SLinus Torvalds 1911da177e4SLinus Torvalds move a0, a1 # shift argument registers 1921da177e4SLinus Torvalds move a1, a2 1931da177e4SLinus Torvalds move a2, a3 1941da177e4SLinus Torvalds lw a3, 16(sp) 1951da177e4SLinus Torvalds lw t4, 20(sp) 1961da177e4SLinus Torvalds lw t5, 24(sp) 1971da177e4SLinus Torvalds lw t6, 28(sp) 1981da177e4SLinus Torvalds sw t4, 16(sp) 1991da177e4SLinus Torvalds sw t5, 20(sp) 2001da177e4SLinus Torvalds sw t6, 24(sp) 2011da177e4SLinus Torvalds jr t2 2021da177e4SLinus Torvalds /* Unreached */ 2031da177e4SLinus Torvalds 204fb498e25SAtsushi Nemotoeinval: li v0, -ENOSYS 2051da177e4SLinus Torvalds jr ra 2061da177e4SLinus Torvalds END(sys_syscall) 2071da177e4SLinus Torvalds 2086a00cb61SFiroz Khan#ifdef CONFIG_MIPS_MT_FPAFF 2096a00cb61SFiroz Khan /* 2106a00cb61SFiroz Khan * For FPU affinity scheduling on MIPS MT processors, we need to 2116a00cb61SFiroz Khan * intercept sys_sched_xxxaffinity() calls until we get a proper hook 2126a00cb61SFiroz Khan * in kernel/sched/core.c. Considered only temporary we only support 2136a00cb61SFiroz Khan * these hooks for the 32-bit kernel - there is no MIPS64 MT processor 2146a00cb61SFiroz Khan * atm. 2156a00cb61SFiroz Khan */ 2166a00cb61SFiroz Khan#define sys_sched_setaffinity mipsmt_sys_sched_setaffinity 2176a00cb61SFiroz Khan#define sys_sched_getaffinity mipsmt_sys_sched_getaffinity 2186a00cb61SFiroz Khan#endif /* CONFIG_MIPS_MT_FPAFF */ 2196a00cb61SFiroz Khan 220ecbba30fSMasahiro Yamada#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) 221fa62f39dSThomas Bogendoerfer#define __SYSCALL(nr, entry) PTR_WD entry 22246e12c07SRalf Baechle .align 2 22346e12c07SRalf Baechle .type sys_call_table, @object 22446e12c07SRalf BaechleEXPORT(sys_call_table) 225ecbba30fSMasahiro Yamada#include <asm/syscall_table_o32.h> 226