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