a42e0e8caa7b229292954bd2e1a33fb1865ce307
[linux-2.6.git] / arch / mips / kernel / scall32-o32.S
1 /*
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
4  * for more details.
5  *
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
9  */
10 #include <linux/config.h>
11 #include <linux/errno.h>
12 #include <asm/asm.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>
21 #include <asm/war.h>
22 #include <asm/asm-offsets.h>
23
24 /* Highest syscall used of any syscall flavour */
25 #define MAX_SYSCALL_NO  __NR_O32_Linux + __NR_O32_Linux_syscalls
26
27         .align  5
28 NESTED(handle_sys, PT_SIZE, sp)
29         .set    noat
30         SAVE_SOME
31         STI
32         .set    at
33
34         lw      t1, PT_EPC(sp)          # skip syscall on return
35
36 #if defined(CONFIG_BINFMT_IRIX)
37         sltiu   t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
38 #else
39         subu    v0, v0, __NR_O32_Linux  # check syscall number
40         sltiu   t0, v0, __NR_O32_Linux_syscalls + 1
41 #endif
42         addiu   t1, 4                   # skip to next instruction
43         sw      t1, PT_EPC(sp)
44         beqz    t0, illegal_syscall
45
46         sll     t0, v0, 3
47         la      t1, sys_call_table
48         addu    t1, t0
49         lw      t2, (t1)                # syscall routine
50         lw      t3, 4(t1)               # >= 0 if we need stack arguments
51         beqz    t2, illegal_syscall
52
53         sw      a3, PT_R26(sp)          # save a3 for syscall restarting
54         bgez    t3, stackargs
55
56 stack_done:
57         lw      t0, TI_FLAGS($28)       # syscall tracing enabled?
58         li      t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
59         and     t0, t1
60         bnez    t0, syscall_trace_entry # -> yes
61
62         jalr    t2                      # Do The Real Thing (TM)
63
64         li      t0, -EMAXERRNO - 1      # error?
65         sltu    t0, t0, v0
66         sw      t0, PT_R7(sp)           # set error flag
67         beqz    t0, 1f
68
69         negu    v0                      # error
70         sw      v0, PT_R0(sp)           # set flag for syscall
71                                         # restarting
72 1:      sw      v0, PT_R2(sp)           # result
73
74 o32_syscall_exit:
75         local_irq_disable               # make sure need_resched and
76                                         # signals dont change between
77                                         # sampling and return
78         lw      a2, TI_FLAGS($28)       # current->work
79         li      t0, _TIF_ALLWORK_MASK
80         and     t0, a2
81         bnez    t0, o32_syscall_exit_work
82
83         j       restore_partial
84
85 o32_syscall_exit_work:
86         j       syscall_exit_work_partial
87
88 /* ------------------------------------------------------------------------ */
89
90 syscall_trace_entry:
91         SAVE_STATIC
92         move    s0, t2
93         move    a0, sp
94         li      a1, 0
95         jal     do_syscall_trace
96
97         move    t0, s0
98         RESTORE_STATIC
99         lw      a0, PT_R4(sp)           # Restore argument registers
100         lw      a1, PT_R5(sp)
101         lw      a2, PT_R6(sp)
102         lw      a3, PT_R7(sp)
103         jalr    t0
104
105         li      t0, -EMAXERRNO - 1      # error?
106         sltu    t0, t0, v0
107         sw      t0, PT_R7(sp)           # set error flag
108         beqz    t0, 1f
109
110         negu    v0                      # error
111         sw      v0, PT_R0(sp)           # set flag for syscall
112                                         # restarting
113 1:      sw      v0, PT_R2(sp)           # result
114
115         j       syscall_exit
116
117 /* ------------------------------------------------------------------------ */
118
119         /*
120          * More than four arguments.  Try to deal with it by copying the
121          * stack arguments from the user stack to the kernel stack.
122          * This Sucks (TM).
123          */
124 stackargs:
125         lw      t0, PT_R29(sp)          # get old user stack pointer
126
127         /*
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.
130          */
131         lw      t5, TI_ADDR_LIMIT($28)
132         addu    t4, t0, 32
133         and     t5, t4
134         bltz    t5, bad_stack           # -> sp is bad
135
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.
139          */
140
141         la      t1, 5f                  # load up to 3 arguments
142         subu    t1, t3
143 1:      lw      t5, 16(t0)              # argument #5 from usp
144         .set    push
145         .set    noreorder
146         .set    nomacro
147         jr      t1
148          addiu  t1, 6f - 5f
149
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
153 5:      jr      t1
154          sw     t5, 16(sp)              # argument #5 to ksp
155
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
160          nop
161         .set    pop
162
163         .section __ex_table,"a"
164         PTR     1b,bad_stack
165         PTR     2b,bad_stack
166         PTR     3b,bad_stack
167         PTR     4b,bad_stack
168         .previous
169
170         /*
171          * The stackpointer for a call with more than 4 arguments is bad.
172          * We probably should handle this case a bit more drastic.
173          */
174 bad_stack:
175         negu    v0                              # error
176         sw      v0, PT_R0(sp)
177         sw      v0, PT_R2(sp)
178         li      t0, 1                           # set error flag
179         sw      t0, PT_R7(sp)
180         j       o32_syscall_exit
181
182         /*
183          * The system call does not exist in this kernel
184          */
185 illegal_syscall:
186         li      v0, -ENOSYS                     # error
187         sw      v0, PT_R2(sp)
188         li      t0, 1                           # set error flag
189         sw      t0, PT_R7(sp)
190         j       o32_syscall_exit
191         END(handle_sys)
192
193         LEAF(mips_atomic_set)
194         andi    v0, a1, 3                       # must be word aligned
195         bnez    v0, bad_alignment
196
197         lw      v1, TI_ADDR_LIMIT($28)          # in legal address range?
198         addiu   a0, a1, 4
199         or      a0, a0, a1
200         and     a0, a0, v1
201         bltz    a0, bad_address
202
203 #ifdef CONFIG_CPU_HAS_LLSC
204         /* Ok, this is the ll/sc case.  World is sane :-)  */
205 1:      ll      v0, (a1)
206         move    a0, a2
207 2:      sc      a0, (a1)
208 #if R10000_LLSC_WAR
209         beqzl   a0, 1b
210 #else
211         beqz    a0, 1b
212 #endif
213
214         .section __ex_table,"a"
215         PTR     1b, bad_stack
216         PTR     2b, bad_stack
217         .previous
218 #else
219         sw      a1, 16(sp)
220         sw      a2, 20(sp)
221
222         move    a0, sp
223         move    a2, a1
224         li      a1, 1
225         jal     do_page_fault
226
227         lw      a1, 16(sp)
228         lw      a2, 20(sp)
229
230         /*
231          * At this point the page should be readable and writable unless
232          * there was no more memory available.
233          */
234 1:      lw      v0, (a1)
235 2:      sw      a2, (a1)
236
237         .section __ex_table,"a"
238         PTR     1b, no_mem
239         PTR     2b, no_mem
240         .previous
241 #endif
242
243         sw      zero, PT_R7(sp)         # success
244         sw      v0, PT_R2(sp)           # result
245
246         j       o32_syscall_exit        # continue like a normal syscall
247
248 no_mem: li      v0, -ENOMEM
249         jr      ra
250
251 bad_address:
252         li      v0, -EFAULT
253         jr      ra
254
255 bad_alignment:
256         li      v0, -EINVAL
257         jr      ra
258         END(mips_atomic_set)
259
260         LEAF(sys_sysmips)
261         beq     a0, MIPS_ATOMIC_SET, mips_atomic_set
262         j       _sys_sysmips
263         END(sys_sysmips)
264
265         LEAF(sys_syscall)
266 #if defined(CONFIG_BINFMT_IRIX)
267         sltiu   v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
268 #else
269         subu    t0, a0, __NR_O32_Linux  # check syscall number
270         sltiu   v0, t0, __NR_O32_Linux_syscalls + 1
271 #endif
272         sll     t1, t0, 3
273         beqz    v0, einval
274
275         lw      t2, sys_call_table(t1)          # syscall routine
276
277 #if defined(CONFIG_BINFMT_IRIX)
278         li      v1, 4000                        # nr of sys_syscall
279 #else
280         li      v1, 4000 - __NR_O32_Linux       # index of sys_syscall
281 #endif
282         beq     t0, v1, einval                  # do not recurse
283
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. */
288
289         move    a0, a1                          # shift argument registers
290         move    a1, a2
291         move    a2, a3
292         lw      a3, 16(sp)
293         lw      t4, 20(sp)
294         lw      t5, 24(sp)
295         lw      t6, 28(sp)
296         sw      t4, 16(sp)
297         sw      t5, 20(sp)
298         sw      t6, 24(sp)
299         sw      a0, PT_R4(sp)                   # .. and push back a0 - a3, some
300         sw      a1, PT_R5(sp)                   # syscalls expect them there
301         sw      a2, PT_R6(sp)
302         sw      a3, PT_R7(sp)
303         sw      a3, PT_R26(sp)                  # update a3 for syscall restarting
304         jr      t2
305         /* Unreached */
306
307 einval: li      v0, -EINVAL
308         jr      ra
309         END(sys_syscall)
310
311         .macro  fifty ptr, nargs, from=1, to=50
312         sys     \ptr            \nargs
313         .if     \to-\from
314         fifty   \ptr,\nargs,"(\from+1)",\to
315         .endif
316         .endm
317
318         .macro  mille ptr, nargs, from=1, to=20
319         fifty   \ptr,\nargs
320         .if     \to-\from
321         mille   \ptr,\nargs,"(\from+1)",\to
322         .endif
323         .endm
324
325         .macro  syscalltable
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 */
331 #endif
332
333         sys     sys_syscall             8       /* 4000 */
334         sys     sys_exit                1
335         sys     sys_fork                0
336         sys     sys_read                3
337         sys     sys_write               3
338         sys     sys_open                3       /* 4005 */
339         sys     sys_close               1
340         sys     sys_waitpid             3
341         sys     sys_creat               2
342         sys     sys_link                2
343         sys     sys_unlink              1       /* 4010 */
344         sys     sys_execve              0
345         sys     sys_chdir               1
346         sys     sys_time                1
347         sys     sys_mknod               3
348         sys     sys_chmod               2       /* 4015 */
349         sys     sys_lchown              3
350         sys     sys_ni_syscall          0
351         sys     sys_ni_syscall          0       /* was sys_stat */
352         sys     sys_lseek               3
353         sys     sys_getpid              0       /* 4020 */
354         sys     sys_mount               5
355         sys     sys_oldumount           1
356         sys     sys_setuid              1
357         sys     sys_getuid              0
358         sys     sys_stime               1       /* 4025 */
359         sys     sys_ptrace              4
360         sys     sys_alarm               1
361         sys     sys_ni_syscall          0       /* was sys_fstat */
362         sys     sys_pause               0
363         sys     sys_utime               2       /* 4030 */
364         sys     sys_ni_syscall          0
365         sys     sys_ni_syscall          0
366         sys     sys_access              2
367         sys     sys_nice                1
368         sys     sys_ni_syscall          0       /* 4035 */
369         sys     sys_sync                0
370         sys     sys_kill                2
371         sys     sys_rename              2
372         sys     sys_mkdir               2
373         sys     sys_rmdir               1       /* 4040 */
374         sys     sys_dup                 1
375         sys     sys_pipe                0
376         sys     sys_times               1
377         sys     sys_ni_syscall          0
378         sys     sys_brk                 1       /* 4045 */
379         sys     sys_setgid              1
380         sys     sys_getgid              0
381         sys     sys_ni_syscall          0       /* was signal(2) */
382         sys     sys_geteuid             0
383         sys     sys_getegid             0       /* 4050 */
384         sys     sys_acct                1
385         sys     sys_umount              2
386         sys     sys_ni_syscall          0
387         sys     sys_ioctl               3
388         sys     sys_fcntl               3       /* 4055 */
389         sys     sys_ni_syscall          2
390         sys     sys_setpgid             2
391         sys     sys_ni_syscall          0
392         sys     sys_olduname            1
393         sys     sys_umask               1       /* 4060 */
394         sys     sys_chroot              1
395         sys     sys_ustat               2
396         sys     sys_dup2                2
397         sys     sys_getppid             0
398         sys     sys_getpgrp             0       /* 4065 */
399         sys     sys_setsid              0
400         sys     sys_sigaction           3
401         sys     sys_sgetmask            0
402         sys     sys_ssetmask            1
403         sys     sys_setreuid            2       /* 4070 */
404         sys     sys_setregid            2
405         sys     sys_sigsuspend          0
406         sys     sys_sigpending          1
407         sys     sys_sethostname         2
408         sys     sys_setrlimit           2       /* 4075 */
409         sys     sys_getrlimit           2
410         sys     sys_getrusage           2
411         sys     sys_gettimeofday        2
412         sys     sys_settimeofday        2
413         sys     sys_getgroups           2       /* 4080 */
414         sys     sys_setgroups           2
415         sys     sys_ni_syscall          0       /* old_select */
416         sys     sys_symlink             2
417         sys     sys_ni_syscall          0       /* was sys_lstat */
418         sys     sys_readlink            3       /* 4085 */
419         sys     sys_uselib              1
420         sys     sys_swapon              2
421         sys     sys_reboot              3
422         sys     old_readdir             3
423         sys     old_mmap                6       /* 4090 */
424         sys     sys_munmap              2
425         sys     sys_truncate            2
426         sys     sys_ftruncate           2
427         sys     sys_fchmod              2
428         sys     sys_fchown              3       /* 4095 */
429         sys     sys_getpriority         2
430         sys     sys_setpriority         3
431         sys     sys_ni_syscall          0
432         sys     sys_statfs              2
433         sys     sys_fstatfs             2       /* 4100 */
434         sys     sys_ni_syscall          0       /* was ioperm(2) */
435         sys     sys_socketcall          2
436         sys     sys_syslog              3
437         sys     sys_setitimer           3
438         sys     sys_getitimer           2       /* 4105 */
439         sys     sys_newstat             2
440         sys     sys_newlstat            2
441         sys     sys_newfstat            2
442         sys     sys_uname               1
443         sys     sys_ni_syscall          0       /* 4110 was iopl(2) */
444         sys     sys_vhangup             0
445         sys     sys_ni_syscall          0       /* was sys_idle() */
446         sys     sys_ni_syscall          0       /* was sys_vm86 */
447         sys     sys_wait4               4
448         sys     sys_swapoff             1       /* 4115 */
449         sys     sys_sysinfo             1
450         sys     sys_ipc                 6
451         sys     sys_fsync               1
452         sys     sys_sigreturn           0
453         sys     sys_clone               0       /* 4120 */
454         sys     sys_setdomainname       2
455         sys     sys_newuname            1
456         sys     sys_ni_syscall          0       /* sys_modify_ldt */
457         sys     sys_adjtimex            1
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 */
464         sys     sys_quotactl            4
465         sys     sys_getpgid             1
466         sys     sys_fchdir              1
467         sys     sys_bdflush             2
468         sys     sys_sysfs               3       /* 4135 */
469         sys     sys_personality         1
470         sys     sys_ni_syscall          0       /* for afs_syscall */
471         sys     sys_setfsuid            1
472         sys     sys_setfsgid            1
473         sys     sys_llseek              5       /* 4140 */
474         sys     sys_getdents            3
475         sys     sys_select              5
476         sys     sys_flock               2
477         sys     sys_msync               3
478         sys     sys_readv               3       /* 4145 */
479         sys     sys_writev              3
480         sys     sys_cacheflush          3
481         sys     sys_cachectl            3
482         sys     sys_sysmips             4
483         sys     sys_ni_syscall          0       /* 4150 */
484         sys     sys_getsid              1
485         sys     sys_fdatasync           1
486         sys     sys_sysctl              1
487         sys     sys_mlock               2
488         sys     sys_munlock             2       /* 4155 */
489         sys     sys_mlockall            1
490         sys     sys_munlockall          0
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 */
499         sys     sys_nanosleep,          2
500         sys     sys_mremap,             4
501         sys     sys_accept              3
502         sys     sys_bind                3
503         sys     sys_connect             3       /* 4170 */
504         sys     sys_getpeername         3
505         sys     sys_getsockname         3
506         sys     sys_getsockopt          5
507         sys     sys_listen              2
508         sys     sys_recv                4       /* 4175 */
509         sys     sys_recvfrom            6
510         sys     sys_recvmsg             3
511         sys     sys_send                4
512         sys     sys_sendmsg             3
513         sys     sys_sendto              6       /* 4180 */
514         sys     sys_setsockopt          5
515         sys     sys_shutdown            2
516         sys     sys_socket              3
517         sys     sys_socketpair          4
518         sys     sys_setresuid           3       /* 4185 */
519         sys     sys_getresuid           3
520         sys     sys_ni_syscall          0       /* was sys_query_module */
521         sys     sys_poll                3
522         sys     sys_nfsservctl          3
523         sys     sys_setresgid           3       /* 4190 */
524         sys     sys_getresgid           3
525         sys     sys_prctl               5
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 */
534         sys     sys_pwrite64            6
535         sys     sys_chown               3
536         sys     sys_getcwd              2
537         sys     sys_capget              2
538         sys     sys_capset              2       /* 4205 */
539         sys     sys_sigaltstack         0
540         sys     sys_sendfile            4
541         sys     sys_ni_syscall          0
542         sys     sys_ni_syscall          0
543         sys     sys_mmap2               6       /* 4210 */
544         sys     sys_truncate64          4
545         sys     sys_ftruncate64         4
546         sys     sys_stat64              2
547         sys     sys_lstat64             2
548         sys     sys_fstat64             2       /* 4215 */
549         sys     sys_pivot_root          2
550         sys     sys_mincore             3
551         sys     sys_madvise             3
552         sys     sys_getdents64          3
553         sys     sys_fcntl64             3       /* 4220 */
554         sys     sys_ni_syscall          0
555         sys     sys_gettid              0
556         sys     sys_readahead           5
557         sys     sys_setxattr            5
558         sys     sys_lsetxattr           5       /* 4225 */
559         sys     sys_fsetxattr           5
560         sys     sys_getxattr            4
561         sys     sys_lgetxattr           4
562         sys     sys_fgetxattr           4
563         sys     sys_listxattr           3       /* 4230 */
564         sys     sys_llistxattr          3
565         sys     sys_flistxattr          3
566         sys     sys_removexattr         2
567         sys     sys_lremovexattr        2
568         sys     sys_fremovexattr        2       /* 4235 */
569         sys     sys_tkill               2
570         sys     sys_sendfile64          5
571         sys     sys_futex               6
572         sys     sys_sched_setaffinity   3
573         sys     sys_sched_getaffinity   3       /* 4240 */
574         sys     sys_io_setup            2
575         sys     sys_io_destroy          1
576         sys     sys_io_getevents        5
577         sys     sys_io_submit           3
578         sys     sys_io_cancel           3       /* 4245 */
579         sys     sys_exit_group          1
580         sys     sys_lookup_dcookie      4
581         sys     sys_epoll_create        1
582         sys     sys_epoll_ctl           4
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 */
589         sys     sys_fstatfs64           2
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 */
599         sys     sys_tgkill              3
600         sys     sys_utimes              2
601         sys     sys_mbind               4
602         sys     sys_ni_syscall          0       /* sys_get_mempolicy */
603         sys     sys_ni_syscall          0       /* 4270 sys_set_mempolicy */
604         sys     sys_mq_open             4
605         sys     sys_mq_unlink           1
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 */
611         sys     sys_waitid              5
612         sys     sys_ni_syscall          0       /* available, was setaltroot */
613         sys     sys_add_key             5       /* 4280 */
614         sys     sys_request_key         4
615         sys     sys_keyctl              5
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         .endm
621
622         /* We pre-compute the number of _instruction_ bytes needed to
623            load or store the arguments 6-8. Negative values are ignored. */
624
625         .macro  sys function, nargs
626         PTR     \function
627         LONG    (\nargs << 2) - (5 << 2)
628         .endm
629
630         .align  3
631         .type   sys_call_table,@object
632 EXPORT(sys_call_table)
633         syscalltable
634         .size   sys_call_table, . - sys_call_table