2  * This file is subject to the terms and conditions of the GNU General Public
 
   3  * License.  See the file "COPYING" in the main directory of this archive
 
   6  * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
 
   7  * Copyright (C) 2001 MIPS Technologies, Inc.
 
   8  * Copyright (C) 2004 Thiemo Seufer
 
  10 #include <linux/config.h>
 
  11 #include <linux/errno.h>
 
  13 #include <asm/asmmacro.h>
 
  14 #include <asm/mipsregs.h>
 
  15 #include <asm/regdef.h>
 
  16 #include <asm/stackframe.h>
 
  17 #include <asm/isadep.h>
 
  18 #include <asm/sysmips.h>
 
  19 #include <asm/thread_info.h>
 
  20 #include <asm/unistd.h>
 
  22 #include <asm/asm-offsets.h>
 
  24 /* Highest syscall used of any syscall flavour */
 
  25 #define MAX_SYSCALL_NO  __NR_O32_Linux + __NR_O32_Linux_syscalls
 
  28 NESTED(handle_sys, PT_SIZE, sp)
 
  34         lw      t1, PT_EPC(sp)          # skip syscall on return
 
  36 #if defined(CONFIG_BINFMT_IRIX)
 
  37         sltiu   t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
 
  39         subu    v0, v0, __NR_O32_Linux  # check syscall number
 
  40         sltiu   t0, v0, __NR_O32_Linux_syscalls + 1
 
  42         addiu   t1, 4                   # skip to next instruction
 
  44         beqz    t0, illegal_syscall
 
  49         lw      t2, (t1)                # syscall routine
 
  50         lw      t3, 4(t1)               # >= 0 if we need stack arguments
 
  51         beqz    t2, illegal_syscall
 
  53         sw      a3, PT_R26(sp)          # save a3 for syscall restarting
 
  57         lw      t0, TI_FLAGS($28)       # syscall tracing enabled?
 
  58         li      t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
 
  60         bnez    t0, syscall_trace_entry # -> yes
 
  62         jalr    t2                      # Do The Real Thing (TM)
 
  64         li      t0, -EMAXERRNO - 1      # error?
 
  66         sw      t0, PT_R7(sp)           # set error flag
 
  70         sw      v0, PT_R0(sp)           # set flag for syscall
 
  72 1:      sw      v0, PT_R2(sp)           # result
 
  75         local_irq_disable               # make sure need_resched and
 
  76                                         # signals dont change between
 
  78         lw      a2, TI_FLAGS($28)       # current->work
 
  79         li      t0, _TIF_ALLWORK_MASK
 
  81         bnez    t0, o32_syscall_exit_work
 
  85 o32_syscall_exit_work:
 
  86         j       syscall_exit_work_partial
 
  88 /* ------------------------------------------------------------------------ */
 
  99         lw      a0, PT_R4(sp)           # Restore argument registers
 
 105         li      t0, -EMAXERRNO - 1      # error?
 
 107         sw      t0, PT_R7(sp)           # set error flag
 
 111         sw      v0, PT_R0(sp)           # set flag for syscall
 
 113 1:      sw      v0, PT_R2(sp)           # result
 
 117 /* ------------------------------------------------------------------------ */
 
 120          * More than four arguments.  Try to deal with it by copying the
 
 121          * stack arguments from the user stack to the kernel stack.
 
 125         lw      t0, PT_R29(sp)          # get old user stack pointer
 
 128          * We intentionally keep the kernel stack a little below the top of
 
 129          * userspace so we don't have to do a slower byte accurate check here.
 
 131         lw      t5, TI_ADDR_LIMIT($28)
 
 134         bltz    t5, bad_stack           # -> sp is bad
 
 136         /* Ok, copy the args from the luser stack to the kernel stack.
 
 137          * t3 is the precomputed number of instruction bytes needed to
 
 138          * load or store arguments 6-8.
 
 141         la      t1, 5f                  # load up to 3 arguments
 
 143 1:      lw      t5, 16(t0)              # argument #5 from usp
 
 150 2:      lw      t8, 28(t0)              # argument #8 from usp
 
 151 3:      lw      t7, 24(t0)              # argument #7 from usp
 
 152 4:      lw      t6, 20(t0)              # argument #6 from usp
 
 154          sw     t5, 16(sp)              # argument #5 to ksp
 
 156         sw      t8, 28(sp)              # argument #8 to ksp
 
 157         sw      t7, 24(sp)              # argument #7 to ksp
 
 158         sw      t6, 20(sp)              # argument #6 to ksp
 
 159 6:      j       stack_done              # go back
 
 163         .section __ex_table,"a"
 
 171          * The stackpointer for a call with more than 4 arguments is bad.
 
 172          * We probably should handle this case a bit more drastic.
 
 178         li      t0, 1                           # set error flag
 
 183          * The system call does not exist in this kernel
 
 186         li      v0, -ENOSYS                     # error
 
 188         li      t0, 1                           # set error flag
 
 193         LEAF(mips_atomic_set)
 
 194         andi    v0, a1, 3                       # must be word aligned
 
 195         bnez    v0, bad_alignment
 
 197         lw      v1, TI_ADDR_LIMIT($28)          # in legal address range?
 
 203 #ifdef CONFIG_CPU_HAS_LLSC
 
 204         /* Ok, this is the ll/sc case.  World is sane :-)  */
 
 214         .section __ex_table,"a"
 
 231          * At this point the page should be readable and writable unless
 
 232          * there was no more memory available.
 
 237         .section __ex_table,"a"
 
 243         sw      zero, PT_R7(sp)         # success
 
 244         sw      v0, PT_R2(sp)           # result
 
 246         j       o32_syscall_exit        # continue like a normal syscall
 
 248 no_mem: li      v0, -ENOMEM
 
 261         beq     a0, MIPS_ATOMIC_SET, mips_atomic_set
 
 266 #if defined(CONFIG_BINFMT_IRIX)
 
 267         sltiu   v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
 
 269         subu    t0, a0, __NR_O32_Linux  # check syscall number
 
 270         sltiu   v0, t0, __NR_O32_Linux_syscalls + 1
 
 275         lw      t2, sys_call_table(t1)          # syscall routine
 
 277 #if defined(CONFIG_BINFMT_IRIX)
 
 278         li      v1, 4000                        # nr of sys_syscall
 
 280         li      v1, 4000 - __NR_O32_Linux       # index of sys_syscall
 
 282         beq     t0, v1, einval                  # do not recurse
 
 284         /* Some syscalls like execve get their arguments from struct pt_regs
 
 285            and claim zero arguments in the syscall table. Thus we have to
 
 286            assume the worst case and shuffle around all potential arguments.
 
 287            If you want performance, don't use indirect syscalls. */
 
 289         move    a0, a1                          # shift argument registers
 
 299         sw      a0, PT_R4(sp)                   # .. and push back a0 - a3, some
 
 300         sw      a1, PT_R5(sp)                   # syscalls expect them there
 
 303         sw      a3, PT_R26(sp)                  # update a3 for syscall restarting
 
 307 einval: li      v0, -EINVAL
 
 311         .macro  fifty ptr, nargs, from=1, to=50
 
 314         fifty   \ptr,\nargs,"(\from+1)",\to
 
 318         .macro  mille ptr, nargs, from=1, to=20
 
 321         mille   \ptr,\nargs,"(\from+1)",\to
 
 326 #if defined(CONFIG_BINFMT_IRIX)
 
 327         mille   sys_ni_syscall          0       /*    0 -  999 SVR4 flavour */
 
 328         mille   sys_ni_syscall          0       /* 1000 - 1999 32-bit IRIX */
 
 329         mille   sys_ni_syscall          0       /* 2000 - 2999 BSD43 flavour */
 
 330         mille   sys_ni_syscall          0       /* 3000 - 3999 POSIX flavour */
 
 333         sys     sys_syscall             8       /* 4000 */
 
 338         sys     sys_open                3       /* 4005 */
 
 343         sys     sys_unlink              1       /* 4010 */
 
 348         sys     sys_chmod               2       /* 4015 */
 
 351         sys     sys_ni_syscall          0       /* was sys_stat */
 
 353         sys     sys_getpid              0       /* 4020 */
 
 358         sys     sys_stime               1       /* 4025 */
 
 361         sys     sys_ni_syscall          0       /* was sys_fstat */
 
 363         sys     sys_utime               2       /* 4030 */
 
 368         sys     sys_ni_syscall          0       /* 4035 */
 
 373         sys     sys_rmdir               1       /* 4040 */
 
 378         sys     sys_brk                 1       /* 4045 */
 
 381         sys     sys_ni_syscall          0       /* was signal(2) */
 
 383         sys     sys_getegid             0       /* 4050 */
 
 388         sys     sys_fcntl               3       /* 4055 */
 
 393         sys     sys_umask               1       /* 4060 */
 
 398         sys     sys_getpgrp             0       /* 4065 */
 
 403         sys     sys_setreuid            2       /* 4070 */
 
 407         sys     sys_sethostname         2
 
 408         sys     sys_setrlimit           2       /* 4075 */
 
 411         sys     sys_gettimeofday        2
 
 412         sys     sys_settimeofday        2
 
 413         sys     sys_getgroups           2       /* 4080 */
 
 415         sys     sys_ni_syscall          0       /* old_select */
 
 417         sys     sys_ni_syscall          0       /* was sys_lstat */
 
 418         sys     sys_readlink            3       /* 4085 */
 
 423         sys     old_mmap                6       /* 4090 */
 
 428         sys     sys_fchown              3       /* 4095 */
 
 429         sys     sys_getpriority         2
 
 430         sys     sys_setpriority         3
 
 433         sys     sys_fstatfs             2       /* 4100 */
 
 434         sys     sys_ni_syscall          0       /* was ioperm(2) */
 
 438         sys     sys_getitimer           2       /* 4105 */
 
 443         sys     sys_ni_syscall          0       /* 4110 was iopl(2) */
 
 445         sys     sys_ni_syscall          0       /* was sys_idle() */
 
 446         sys     sys_ni_syscall          0       /* was sys_vm86 */
 
 448         sys     sys_swapoff             1       /* 4115 */
 
 453         sys     sys_clone               0       /* 4120 */
 
 454         sys     sys_setdomainname       2
 
 456         sys     sys_ni_syscall          0       /* sys_modify_ldt */
 
 458         sys     sys_mprotect            3       /* 4125 */
 
 459         sys     sys_sigprocmask         3
 
 460         sys     sys_ni_syscall          0       /* was create_module */
 
 461         sys     sys_init_module         5
 
 462         sys     sys_delete_module       1
 
 463         sys     sys_ni_syscall          0       /* 4130 was get_kernel_syms */
 
 468         sys     sys_sysfs               3       /* 4135 */
 
 469         sys     sys_personality         1
 
 470         sys     sys_ni_syscall          0       /* for afs_syscall */
 
 473         sys     sys_llseek              5       /* 4140 */
 
 478         sys     sys_readv               3       /* 4145 */
 
 483         sys     sys_ni_syscall          0       /* 4150 */
 
 488         sys     sys_munlock             2       /* 4155 */
 
 491         sys     sys_sched_setparam      2
 
 492         sys     sys_sched_getparam      2
 
 493         sys     sys_sched_setscheduler  3       /* 4160 */
 
 494         sys     sys_sched_getscheduler  1
 
 495         sys     sys_sched_yield         0
 
 496         sys     sys_sched_get_priority_max 1
 
 497         sys     sys_sched_get_priority_min 1
 
 498         sys     sys_sched_rr_get_interval 2     /* 4165 */
 
 503         sys     sys_connect             3       /* 4170 */
 
 504         sys     sys_getpeername         3
 
 505         sys     sys_getsockname         3
 
 508         sys     sys_recv                4       /* 4175 */
 
 513         sys     sys_sendto              6       /* 4180 */
 
 518         sys     sys_setresuid           3       /* 4185 */
 
 520         sys     sys_ni_syscall          0       /* was sys_query_module */
 
 523         sys     sys_setresgid           3       /* 4190 */
 
 526         sys     sys_rt_sigreturn        0
 
 527         sys     sys_rt_sigaction        4
 
 528         sys     sys_rt_sigprocmask      4       /* 4195 */
 
 529         sys     sys_rt_sigpending       2
 
 530         sys     sys_rt_sigtimedwait     4
 
 531         sys     sys_rt_sigqueueinfo     3
 
 532         sys     sys_rt_sigsuspend       0
 
 533         sys     sys_pread64             6       /* 4200 */
 
 538         sys     sys_capset              2       /* 4205 */
 
 539         sys     sys_sigaltstack         0
 
 543         sys     sys_mmap2               6       /* 4210 */
 
 545         sys     sys_ftruncate64         4
 
 548         sys     sys_fstat64             2       /* 4215 */
 
 553         sys     sys_fcntl64             3       /* 4220 */
 
 558         sys     sys_lsetxattr           5       /* 4225 */
 
 563         sys     sys_listxattr           3       /* 4230 */
 
 566         sys     sys_removexattr         2
 
 567         sys     sys_lremovexattr        2
 
 568         sys     sys_fremovexattr        2       /* 4235 */
 
 572         sys     sys_sched_setaffinity   3
 
 573         sys     sys_sched_getaffinity   3       /* 4240 */
 
 576         sys     sys_io_getevents        5
 
 578         sys     sys_io_cancel           3       /* 4245 */
 
 580         sys     sys_lookup_dcookie      4
 
 581         sys     sys_epoll_create        1
 
 583         sys     sys_epoll_wait          3       /* 4250 */
 
 584         sys     sys_remap_file_pages    5
 
 585         sys     sys_set_tid_address     1
 
 586         sys     sys_restart_syscall     0
 
 587         sys     sys_fadvise64_64        7
 
 588         sys     sys_statfs64            3       /* 4255 */
 
 590         sys     sys_timer_create        3
 
 591         sys     sys_timer_settime       4
 
 592         sys     sys_timer_gettime       2
 
 593         sys     sys_timer_getoverrun    1       /* 4260 */
 
 594         sys     sys_timer_delete        1
 
 595         sys     sys_clock_settime       2
 
 596         sys     sys_clock_gettime       2
 
 597         sys     sys_clock_getres        2
 
 598         sys     sys_clock_nanosleep     4       /* 4265 */
 
 602         sys     sys_ni_syscall          0       /* sys_get_mempolicy */
 
 603         sys     sys_ni_syscall          0       /* 4270 sys_set_mempolicy */
 
 606         sys     sys_mq_timedsend        5
 
 607         sys     sys_mq_timedreceive     5
 
 608         sys     sys_mq_notify           2       /* 4275 */
 
 609         sys     sys_mq_getsetattr       3
 
 610         sys     sys_ni_syscall          0       /* sys_vserver */
 
 612         sys     sys_ni_syscall          0       /* available, was setaltroot */
 
 613         sys     sys_add_key             5       /* 4280 */
 
 614         sys     sys_request_key         4
 
 616         sys     sys_set_thread_area     1
 
 617         sys     sys_inotify_init        0
 
 618         sys     sys_inotify_add_watch   3       /* 4285 */
 
 619         sys     sys_inotify_rm_watch    2
 
 620         sys     sys_migrate_pages       4
 
 623         sys     sys_mknodat             4       /* 4290 */
 
 628         sys     sys_renameat            4       /* 4295 */
 
 633         sys     sys_faccessat           3       /* 4300 */
 
 639         /* We pre-compute the number of _instruction_ bytes needed to
 
 640            load or store the arguments 6-8. Negative values are ignored. */
 
 642         .macro  sys function, nargs
 
 644         LONG    (\nargs << 2) - (5 << 2)
 
 648         .type   sys_call_table,@object
 
 649 EXPORT(sys_call_table)
 
 651         .size   sys_call_table, . - sys_call_table