patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / arch / mips / kernel / scall64-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 - 2000, 2001 by Ralf Baechle
7  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8  * Copyright (C) 2001 MIPS Technologies, Inc.
9  *
10  * Hairy, the userspace application uses a different argument passing
11  * convention than the kernel, so we have to translate things from o32
12  * to ABI64 calling convention.  64-bit syscalls are also processed
13  * here for now.
14  */
15 #include <linux/config.h>
16 #include <linux/errno.h>
17 #include <asm/asm.h>
18 #include <asm/asmmacro.h>
19 #include <asm/mipsregs.h>
20 #include <asm/regdef.h>
21 #include <asm/stackframe.h>
22 #include <asm/thread_info.h>
23 #include <asm/unistd.h>
24 #include <asm/sysmips.h>
25
26         .align  5
27 NESTED(handle_sys, PT_SIZE, sp)
28         .set    noat
29         SAVE_SOME
30         STI
31         .set    at
32         ld      t1, PT_EPC(sp)          # skip syscall on return
33
34         subu    t0, v0, __NR_O32_Linux  # check syscall number
35         sltiu   t0, t0, __NR_O32_Linux_syscalls + 1
36         daddiu  t1, 4                   # skip to next instruction
37         sd      t1, PT_EPC(sp)
38         beqz    t0, not_o32_scall
39 #if 0
40  SAVE_ALL
41  move a1, v0
42  PRINT("Scall %ld\n")
43  RESTORE_ALL
44 #endif
45
46         sll     a0, a0, 0
47         sll     a1, a1, 0
48         sll     a2, a2, 0
49         sll     a3, a3, 0
50
51         /* XXX Put both in one cacheline, should save a bit. */
52         dsll    t0, v0, 3               # offset into table
53         ld      t2, (sys_call_table - (__NR_O32_Linux * 8))(t0)
54         lbu     t3, (sys_narg_table - __NR_O32_Linux)(v0)
55
56         subu    t0, t3, 5               # 5 or more arguments?
57         sd      a3, PT_R26(sp)          # save a3 for syscall restarting
58         bgez    t0, stackargs
59
60 stack_done:
61         li      t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
62         LONG_L  t0, TI_FLAGS($28)       # syscall tracing enabled?
63         and     t0, t1, t0
64         bnez    t0, trace_a_syscall
65
66         jalr    t2                      # Do The Real Thing (TM)
67
68         li      t0, -EMAXERRNO - 1      # error?
69         sltu    t0, t0, v0
70         sd      t0, PT_R7(sp)           # set error flag
71         beqz    t0, 1f
72
73         negu    v0                      # error
74         sd      v0, PT_R0(sp)           # flag for syscall restarting
75 1:      sd      v0, PT_R2(sp)           # result
76
77 FEXPORT(o32_syscall_exit)
78         local_irq_disable               # make need_resched and
79                                         # signals dont change between
80                                         # sampling and return
81         LONG_L  a2, TI_FLAGS($28)
82         li      t0, _TIF_ALLWORK_MASK
83         and     t0, a2, t0
84         bnez    t0, o32_syscall_exit_work
85
86         j       restore_partial
87
88 o32_syscall_exit_work:
89         j       syscall_exit_work_partial
90
91 /* ------------------------------------------------------------------------ */
92
93 trace_a_syscall:
94         SAVE_STATIC
95         sd      a4, PT_R8(sp)
96         sd      a5, PT_R9(sp)
97         sd      a6, PT_R10(sp)
98         sd      a7, PT_R11(sp)
99
100         sd      t2,PT_R1(sp)
101         move    a0, sp
102         li      a1, 0
103         jal     do_syscall_trace
104         ld      t2,PT_R1(sp)
105
106         ld      a0, PT_R4(sp)           # Restore argument registers
107         ld      a1, PT_R5(sp)
108         ld      a2, PT_R6(sp)
109         ld      a3, PT_R7(sp)
110         ld      a4, PT_R8(sp)
111         ld      a5, PT_R9(sp)
112
113         jalr    t2
114
115         li      t0, -EMAXERRNO - 1      # error?
116         sltu    t0, t0, v0
117         sd      t0, PT_R7(sp)           # set error flag
118         beqz    t0, 1f
119
120         negu    v0                      # error
121         sd      v0, PT_R0(sp)           # set flag for syscall restarting
122 1:      sd      v0, PT_R2(sp)           # result
123
124         j       syscall_exit
125
126 /* ------------------------------------------------------------------------ */
127
128         /*
129          * More than four arguments.  Try to deal with it by copying the
130          * stack arguments from the user stack to the kernel stack.
131          * This Sucks (TM).
132          */
133 stackargs:
134         ld      t0, PT_R29(sp)          # get old user stack pointer
135         subu    t3, 4
136         sll     t1, t3, 2               # stack valid?
137
138         addu    t1, t0                  # end address
139         or      t0, t1
140         bltz    t0, bad_stack           # -> sp is bad
141
142         ld      t0, PT_R29(sp)          # get old user stack pointer
143         PTR_LA  t1, 3f                  # copy 1 to 2 arguments
144         sll     t3, t3, 2
145         subu    t1, t3
146         jr      t1
147
148         /* Ok, copy the args from the luser stack to the kernel stack */
149         .set    push
150         .set    noreorder
151         .set    nomacro
152 1:      lw      a5, 20(t0)              # argument #6 from usp
153 2:      lw      a4, 16(t0)              # argument #5 from usp
154 3:      .set    pop
155
156         j       stack_done              # go back
157
158         .section __ex_table,"a"
159         PTR     1b, bad_stack
160         PTR     2b, bad_stack
161         .previous
162
163         /*
164          * The stackpointer for a call with more than 4 arguments is bad.
165          */
166 bad_stack:
167         negu    v0                      # error
168         sd      v0, PT_R0(sp)
169         sd      v0, PT_R2(sp)
170         li      t0, 1                   # set error flag
171         sd      t0, PT_R7(sp)
172         j       o32_syscall_exit
173
174 not_o32_scall:
175         /*
176          * This is not an o32 compatibility syscall, pass it on
177          * to the 64-bit syscall handlers.
178          */
179 #ifdef CONFIG_MIPS32_N32
180         j       handle_sysn32
181 #else
182         j       handle_sys64
183 #endif
184
185 illegal_syscall:
186         /* This also isn't a 64-bit syscall, throw an error.  */
187         li      v0, ENOSYS              # error
188         sd      v0, PT_R2(sp)
189         li      t0, 1                   # set error flag
190         sd      t0, PT_R7(sp)
191         j       o32_syscall_exit
192         END(handle_sys)
193
194 LEAF(sys32_syscall)
195         ld      t0, PT_R29(sp)          # user sp
196
197         sltu    v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
198         beqz    v0, enosys
199
200         dsll    v0, a0, 3
201         dla     v1, sys32_syscall
202         ld      t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
203         lbu     t3, (sys_narg_table - __NR_O32_Linux)(a0)
204
205         li      v0, -EINVAL
206         beq     t2, v1, out             # do not recurse
207
208         beqz    t2, enosys              # null function pointer?
209
210         andi    v0, t0, 0x3             # unaligned stack pointer?
211         bnez    v0, sigsegv
212
213         daddiu  v0, t0, 16              # v0 = usp + 16
214         daddu   t1, v0, 12              # 3 32-bit arguments
215         ld      v1, TI_ADDR_LIMIT($28)
216         or      v0, v0, t1
217         and     v1, v1, v0
218         bnez    v1, efault
219
220         move    a0, a1                  # shift argument registers
221         move    a1, a2
222         move    a2, a3
223
224 1:      lw      a3, 16(t0)
225 2:      lw      t3, 20(t0)
226 3:      lw      t1, 24(t0)
227
228         .section __ex_table,"a"
229         PTR     1b, efault
230         PTR     2b, efault
231         PTR     3b, efault
232         .previous
233
234         sw      t3, 16(sp)              # put into new stackframe
235         sw      t1, 20(sp)
236
237         bnez    t1, 1f                  # zero arguments?
238         daddu   a0, sp, 32              # then pass sp in a0
239 1:
240
241         sw      t3, 16(sp)
242         sw      v1, 20(sp)
243         jr      t2
244         /* Unreached */
245
246 enosys: li      v0, -ENOSYS
247         b       out
248
249 sigsegv:
250         li      a0, _SIGSEGV
251         move    a1, $28
252         jal     force_sig
253         /* Fall through */
254
255 efault: li      v0, -EFAULT
256
257 out:    jr      ra
258         END(sys32_syscall)
259
260         .macro  syscalltable
261         sys     sys32_syscall   0                       /* 4000 */
262         sys     sys_exit        1
263         sys     sys_fork        0
264         sys     sys_read        3
265         sys     sys_write       3
266         sys     sys_open        3                       /* 4005 */
267         sys     sys_close       1
268         sys     sys_waitpid     3
269         sys     sys_creat       2
270         sys     sys_link        2
271         sys     sys_unlink      1                       /* 4010 */
272         sys     sys32_execve    0
273         sys     sys_chdir       1
274         sys     sys_time        1
275         sys     sys_mknod       3
276         sys     sys_chmod       2                       /* 4015 */
277         sys     sys_lchown      3
278         sys     sys_ni_syscall  0
279         sys     sys_ni_syscall  0                       /* was sys_stat */
280         sys     sys_lseek       3
281         sys     sys_getpid      0                       /* 4020 */
282         sys     sys_mount       5
283         sys     sys_oldumount   1
284         sys     sys_setuid      1
285         sys     sys_getuid      0
286         sys     sys_stime       1                       /* 4025 */
287         sys     sys32_ptrace    4
288         sys     sys_alarm       1
289         sys     sys_ni_syscall  0                       /* was sys_fstat */
290         sys     sys_pause       0
291         sys     compat_sys_utime        2                       /* 4030 */
292         sys     sys_ni_syscall  0
293         sys     sys_ni_syscall  0
294         sys     sys_access      2
295         sys     sys_nice        1
296         sys     sys_ni_syscall  0                       /* 4035 */
297         sys     sys_sync        0
298         sys     sys_kill        2
299         sys     sys_rename      2
300         sys     sys_mkdir       2
301         sys     sys_rmdir       1                       /* 4040 */
302         sys     sys_dup         1
303         sys     sys_pipe        0
304         sys     compat_sys_times        1
305         sys     sys_ni_syscall  0
306         sys     sys_brk         1                       /* 4045 */
307         sys     sys_setgid      1
308         sys     sys_getgid      0
309         sys     sys_ni_syscall  0       /* was signal   2 */
310         sys     sys_geteuid     0
311         sys     sys_getegid     0                       /* 4050 */
312         sys     sys_acct        0
313         sys     sys_umount      2
314         sys     sys_ni_syscall  0
315         sys     compat_sys_ioctl        3
316         sys     compat_sys_fcntl        3               /* 4055 */
317         sys     sys_ni_syscall  2
318         sys     sys_setpgid     2
319         sys     sys_ni_syscall, 0
320         sys     sys_olduname    1
321         sys     sys_umask       1                       /* 4060 */
322         sys     sys_chroot      1
323         sys     sys32_ustat     2
324         sys     sys_dup2        2
325         sys     sys_getppid     0
326         sys     sys_getpgrp     0                       /* 4065 */
327         sys     sys_setsid      0
328         sys     sys32_sigaction 3
329         sys     sys_sgetmask    0
330         sys     sys_ssetmask    1
331         sys     sys_setreuid    2                       /* 4070 */
332         sys     sys_setregid    2
333         sys     sys32_sigsuspend        0
334         sys     compat_sys_sigpending   1
335         sys     sys_sethostname 2
336         sys     compat_sys_setrlimit    2               /* 4075 */
337         sys     compat_sys_getrlimit    2
338         sys     compat_sys_getrusage    2
339         sys     sys32_gettimeofday 2
340         sys     sys32_settimeofday 2
341         sys     sys_getgroups   2                       /* 4080 */
342         sys     sys_setgroups   2
343         sys     sys_ni_syscall  0                       /* old_select */
344         sys     sys_symlink     2
345         sys     sys_ni_syscall  0                       /* was sys_lstat */
346         sys     sys_readlink    3                       /* 4085 */
347         sys     sys_uselib      1
348         sys     sys_swapon      2
349         sys     sys_reboot      3
350         sys     sys32_readdir   3
351         sys     old_mmap        6                       /* 4090 */
352         sys     sys_munmap      2
353         sys     sys_truncate    2
354         sys     sys_ftruncate   2
355         sys     sys_fchmod      2
356         sys     sys_fchown      3                       /* 4095 */
357         sys     sys_getpriority 2
358         sys     sys_setpriority 3
359         sys     sys_ni_syscall  0
360         sys     compat_sys_statfs       2
361         sys     compat_sys_fstatfs      2               /* 4100 */
362         sys     sys_ni_syscall          0               /* sys_ioperm */
363         sys     sys32_socketcall                2
364         sys     sys_syslog              3
365         sys     compat_sys_setitimer    3
366         sys     compat_sys_getitimer    2       /* 4105 */
367         sys     compat_sys_newstat      2
368         sys     compat_sys_newlstat     2
369         sys     compat_sys_newfstat     2
370         sys     sys_uname               1
371         sys     sys_ni_syscall          0       /* sys_ioperm  *//* 4110 */
372         sys     sys_vhangup             0
373         sys     sys_ni_syscall          0       /* was sys_idle  */
374         sys     sys_ni_syscall          0       /* sys_vm86 */
375         sys     sys32_wait4             4
376         sys     sys_swapoff             1       /* 4115 */
377         sys     sys32_sysinfo           1
378         sys     sys32_ipc               6
379         sys     sys_fsync       1
380         sys     sys32_sigreturn 0
381         sys     sys_clone       0                       /* 4120 */
382         sys     sys_setdomainname 2
383         sys     sys32_newuname  1
384         sys     sys_ni_syscall  0       /* sys_modify_ldt */
385         sys     sys32_adjtimex  1
386         sys     sys_mprotect    3                       /* 4125 */
387         sys     compat_sys_sigprocmask  3
388         sys     sys_ni_syscall  0                       /* was creat_module */
389         sys     sys_init_module 5
390         sys     sys_delete_module 1
391         sys     sys_ni_syscall  0               /* 4130, get_kernel_syms */
392         sys     sys_quotactl    0
393         sys     sys_getpgid     1
394         sys     sys_fchdir      1
395         sys     sys_bdflush     2
396         sys     sys_sysfs       3                       /* 4135 */
397         sys     sys32_personality       1
398         sys     sys_ni_syscall  0 /* for afs_syscall */
399         sys     sys_setfsuid    1
400         sys     sys_setfsgid    1
401         sys     sys32_llseek    5                       /* 4140 */
402         sys     sys32_getdents  3
403         sys     compat_sys_select       5
404         sys     sys_flock       2
405         sys     sys_msync       3
406         sys     compat_sys_readv        3               /* 4145 */
407         sys     compat_sys_writev       3
408         sys     sys_cacheflush  3
409         sys     sys_cachectl    3
410         sys     sys_sysmips     4
411         sys     sys_ni_syscall  0                       /* 4150 */
412         sys     sys_getsid      1
413         sys     sys_fdatasync   0
414         sys     sys32_sysctl    1
415         sys     sys_mlock       2
416         sys     sys_munlock     2                       /* 4155 */
417         sys     sys_mlockall    1
418         sys     sys_munlockall  0
419         sys     sys_sched_setparam 2
420         sys     sys_sched_getparam 2
421         sys     sys_sched_setscheduler 3                /* 4160 */
422         sys     sys_sched_getscheduler 1
423         sys     sys_sched_yield 0
424         sys     sys_sched_get_priority_max 1
425         sys     sys_sched_get_priority_min 1
426         sys     sys32_sched_rr_get_interval 2           /* 4165 */
427         sys     compat_sys_nanosleep    2
428         sys     sys_mremap      4
429         sys     sys_accept      3
430         sys     sys_bind        3
431         sys     sys_connect     3                       /* 4170 */
432         sys     sys_getpeername 3
433         sys     sys_getsockname 3
434         sys     sys_getsockopt  5
435         sys     sys_listen      2
436         sys     sys_recv        4                       /* 4175 */
437         sys     sys_recvfrom    6
438         sys     compat_sys_recvmsg      3
439         sys     sys_send        4
440         sys     compat_sys_sendmsg      3
441         sys     sys_sendto      6                       /* 4180 */
442         sys     compat_sys_setsockopt   5
443         sys     sys_shutdown    2
444         sys     sys_socket      3
445         sys     sys_socketpair  4
446         sys     sys_setresuid   3                       /* 4185 */
447         sys     sys_getresuid   3
448         sys     sys_ni_syscall  0                       /* was query_module */
449         sys     sys_poll        3
450         sys     sys_nfsservctl  3
451         sys     sys_setresgid   3                       /* 4190 */
452         sys     sys_getresgid   3
453         sys     sys_prctl       5
454         sys     sys32_rt_sigreturn 0
455         sys     sys32_rt_sigaction 4
456         sys     sys32_rt_sigprocmask 4                  /* 4195 */
457         sys     sys32_rt_sigpending 2
458         sys     sys32_rt_sigtimedwait 4
459         sys     sys32_rt_sigqueueinfo 3
460         sys     sys32_rt_sigsuspend 0
461         sys     sys32_pread     6                       /* 4200 */
462         sys     sys32_pwrite    6
463         sys     sys_chown       3
464         sys     sys_getcwd      2
465         sys     sys_capget      2
466         sys     sys_capset      2                       /* 4205 */
467         sys     sys32_sigaltstack       0
468         sys     sys32_sendfile  4
469         sys     sys_ni_syscall  0
470         sys     sys_ni_syscall  0
471         sys     sys32_mmap2     6                       /* 4210 */
472         sys     sys32_truncate64        4
473         sys     sys32_ftruncate64       4
474         sys     sys_newstat     2
475         sys     sys_newlstat    2
476         sys     sys_newfstat    2                       /* 4215 */
477         sys     sys_pivot_root  2
478         sys     sys_mincore     3
479         sys     sys_madvise     3
480         sys     sys_getdents64  3
481         sys     compat_sys_fcntl64      3               /* 4220 */
482         sys     sys_ni_syscall  0
483         sys     sys_gettid      0
484         sys     sys32_readahead 5
485         sys     sys_setxattr    5
486         sys     sys_lsetxattr   5                       /* 4225 */
487         sys     sys_fsetxattr   5
488         sys     sys_getxattr    4
489         sys     sys_lgetxattr   4
490         sys     sys_fgetxattr   4
491         sys     sys_listxattr   3                       /* 4230 */
492         sys     sys_llistxattr  3
493         sys     sys_flistxattr  3
494         sys     sys_removexattr 2
495         sys     sys_lremovexattr        2
496         sys     sys_fremovexattr        2               /* 4235 */
497         sys     sys_tkill               2
498         sys     sys_sendfile64          5
499         sys     compat_sys_futex        5
500         sys     compat_sys_sched_setaffinity    3
501         sys     compat_sys_sched_getaffinity    3       /* 4240 */
502         sys     sys_io_setup            2
503         sys     sys_io_destroy          1
504         sys     sys_io_getevents        5
505         sys     sys_io_submit           3
506         sys     sys_io_cancel           3               /* 4245 */
507         sys     sys_exit_group          1
508         sys     sys_lookup_dcookie      3
509         sys     sys_epoll_create        1
510         sys     sys_epoll_ctl           4
511         sys     sys_epoll_wait          3               /* 4250 */
512         sys     sys_remap_file_pages    5
513         sys     sys_set_tid_address     1
514         sys     sys_restart_syscall     0
515         sys     sys_fadvise64_64        7
516         sys     sys_statfs64            3               /* 4255 */
517         sys     sys_fstatfs64           2
518         sys     sys_timer_create        3
519         sys     sys_timer_settime       4
520         sys     sys_timer_gettime       2
521         sys     sys_timer_getoverrun    1               /* 4260 */
522         sys     sys_timer_delete        1
523         sys     sys_clock_settime       2
524         sys     sys_clock_gettime       2
525         sys     sys_clock_getres        2
526         sys     sys_clock_nanosleep     4               /* 4265 */
527         sys     sys_tgkill              3
528         sys     compat_sys_utimes       2
529         sys     sys_ni_syscall          0       /* sys_mbind */
530         sys     sys_ni_syscall          0       /* sys_get_mempolicy */
531         sys     sys_ni_syscall          0       /* 4270 sys_set_mempolicy */
532         sys     compat_sys_mq_open      4
533         sys     sys_mq_unlink           1
534         sys     compat_sys_mq_timedsend 5
535         sys     compat_sys_mq_timedreceive 5
536         sys     compat_sys_mq_notify    2       /* 4275 */
537         sys     compat_sys_mq_getsetattr 3
538
539         .endm
540
541         .macro  sys function, nargs
542         PTR     \function
543         .endm
544
545         .align  3
546 sys_call_table:
547         syscalltable
548
549         .macro  sys function, nargs
550         .byte   \nargs
551         .endm
552
553 sys_narg_table:
554         syscalltable