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