^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1995-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2001 MIPS Technologies, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2004 Thiemo Seufer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2014 Imagination Technologies Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/regdef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/stackframe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/isadep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/sysmips.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/war.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) NESTED(handle_sys, PT_SIZE, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) SAVE_SOME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) TRACE_IRQS_ON_RELOAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) STI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .set at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) lw t1, PT_EPC(sp) # skip syscall on return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) addiu t1, 4 # skip to next instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) sw t1, PT_EPC(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) sw a3, PT_R26(sp) # save a3 for syscall restarting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * More than four arguments. Try to deal with it by copying the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * stack arguments from the user stack to the kernel stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * This Sucks (TM).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) lw t0, PT_R29(sp) # get old user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * We intentionally keep the kernel stack a little below the top of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * userspace so we don't have to do a slower byte accurate check here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) lw t5, TI_ADDR_LIMIT($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) addu t4, t0, 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) and t5, t4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) bltz t5, bad_stack # -> sp is bad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Ok, copy the args from the luser stack to the kernel stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .set push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .set nomacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) load_a4: user_lw(t5, 16(t0)) # argument #5 from usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) load_a5: user_lw(t6, 20(t0)) # argument #6 from usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) load_a6: user_lw(t7, 24(t0)) # argument #7 from usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) load_a7: user_lw(t8, 28(t0)) # argument #8 from usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) loads_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) sw t5, 16(sp) # argument #5 to ksp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) sw t6, 20(sp) # argument #6 to ksp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) sw t7, 24(sp) # argument #7 to ksp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) sw t8, 28(sp) # argument #8 to ksp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .set pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .section __ex_table,"a"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) PTR load_a4, bad_stack_a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) PTR load_a5, bad_stack_a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) PTR load_a6, bad_stack_a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) PTR load_a7, bad_stack_a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) lw t0, TI_FLAGS($28) # syscall tracing enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) li t1, _TIF_WORK_SYSCALL_ENTRY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) and t0, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) bnez t0, syscall_trace_entry # -> yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) syscall_common:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) subu v0, v0, __NR_O32_Linux # check syscall number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) sltiu t0, v0, __NR_O32_Linux_syscalls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) beqz t0, illegal_syscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) sll t0, v0, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) la t1, sys_call_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) addu t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) lw t2, (t1) # syscall routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) beqz t2, illegal_syscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) jalr t2 # Do The Real Thing (TM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) li t0, -EMAXERRNO - 1 # error?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) sltu t0, t0, v0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) sw t0, PT_R7(sp) # set error flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) beqz t0, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) lw t1, PT_R2(sp) # syscall number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) negu v0 # error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) sw t1, PT_R0(sp) # save it for syscall restarting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 1: sw v0, PT_R2(sp) # result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) o32_syscall_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) j syscall_exit_partial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* ------------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) syscall_trace_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) SAVE_STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) move a0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * syscall number is in v0 unless we called syscall(__NR_###)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * where the real syscall number is in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) move a1, v0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) subu t2, v0, __NR_O32_Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) bnez t2, 1f /* __NR_syscall at offset 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) lw a1, PT_R4(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 1: jal syscall_trace_enter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bltz v0, 1f # seccomp failed? Skip syscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) RESTORE_STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) lw v0, PT_R2(sp) # Restore syscall (maybe modified)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) lw a0, PT_R4(sp) # Restore argument registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) lw a1, PT_R5(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) lw a2, PT_R6(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) lw a3, PT_R7(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) j syscall_common
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 1: j syscall_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* ------------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * Our open-coded access area sanity test for the stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * failed. We probably should handle this case a bit more drastic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) bad_stack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) li v0, EFAULT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) sw v0, PT_R2(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) li t0, 1 # set error flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) sw t0, PT_R7(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) j o32_syscall_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) bad_stack_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) li t5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) b load_a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) bad_stack_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) li t6, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) b load_a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) bad_stack_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) li t7, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) b load_a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) bad_stack_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) li t8, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) b loads_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * The system call does not exist in this kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) illegal_syscall:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) li v0, ENOSYS # error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) sw v0, PT_R2(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) li t0, 1 # set error flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) sw t0, PT_R7(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) j o32_syscall_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) END(handle_sys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) LEAF(sys_syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) subu t0, a0, __NR_O32_Linux # check syscall number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) sltiu v0, t0, __NR_O32_Linux_syscalls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) beqz t0, einval # do not recurse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) sll t1, t0, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) beqz v0, einval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) lw t2, sys_call_table(t1) # syscall routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) move a0, a1 # shift argument registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) move a1, a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) move a2, a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) lw a3, 16(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) lw t4, 20(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) lw t5, 24(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) lw t6, 28(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) sw t4, 16(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) sw t5, 20(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) sw t6, 24(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) jr t2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Unreached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) einval: li v0, -ENOSYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) jr ra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) END(sys_syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #ifdef CONFIG_MIPS_MT_FPAFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * For FPU affinity scheduling on MIPS MT processors, we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * intercept sys_sched_xxxaffinity() calls until we get a proper hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * in kernel/sched/core.c. Considered only temporary we only support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * atm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define sys_sched_setaffinity mipsmt_sys_sched_setaffinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define sys_sched_getaffinity mipsmt_sys_sched_getaffinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #endif /* CONFIG_MIPS_MT_FPAFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define __SYSCALL(nr, entry) PTR entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .type sys_call_table, @object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) EXPORT(sys_call_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #include <asm/syscall_table_32_o32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #undef __SYSCALL