patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / arch / mips / kernel / scall64-64.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) 1999, 2000 Silicon Graphics, Inc.
8  * Copyright (C) 2001 MIPS Technologies, Inc.
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/offset.h>
18 #include <asm/sysmips.h>
19 #include <asm/thread_info.h>
20 #include <asm/unistd.h>
21
22 #ifndef CONFIG_BINFMT_ELF32
23 /* Neither O32 nor N32, so define handle_sys here */
24 #define handle_sys64 handle_sys
25 #endif
26
27         .align  5
28 NESTED(handle_sys64, PT_SIZE, sp)
29 #if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
30         /*
31          * When 32-bit compatibility is configured scall_o32.S
32          * already did this.
33          */
34         .set    noat
35         SAVE_SOME
36         STI
37         .set    at
38 #endif
39
40 FEXPORT(__handle_sys64)
41         subu    t0, v0, __NR_64_Linux   # check syscall number
42         sltiu   t0, t0, __NR_64_Linux_syscalls + 1
43 #if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
44         ld      t1, PT_EPC(sp)          # skip syscall on return
45         daddiu  t1, 4                   # skip to next instruction
46         sd      t1, PT_EPC(sp)
47 #endif
48         beqz    t0, illegal_syscall
49
50         dsll    t0, v0, 3               # offset into table
51         ld      t2, (sys_call_table - (__NR_64_Linux * 8))(t0)
52                                         # syscall routine
53
54         sd      a3, PT_R26(sp)          # save a3 for syscall restarting
55
56         LONG_L  t0, TI_FLAGS($28)
57         bltz    t0, syscall_trace_entry # syscall tracing enabled?
58
59         jalr    t2                      # Do The Real Thing (TM)
60
61         li      t0, -EMAXERRNO - 1      # error?
62         sltu    t0, t0, v0
63         sd      t0, PT_R7(sp)           # set error flag
64         beqz    t0, 1f
65
66         negu    v0                      # error
67         sd      v0, PT_R0(sp)           # set flag for syscall
68                                         # restarting
69 1:      sd      v0, PT_R2(sp)           # result
70
71 syscall_exit:
72         local_irq_disable               # make sure need_resched and
73                                         # signals dont change between
74                                         # sampling and return
75         LONG_L  a2, TI_FLAGS($28)       # current->work
76         li      t0, _TIF_ALLWORK_MASK
77         and     t0, a2, t0
78         bnez    t0, n64_syscall_exit_work
79
80         j       restore_partial
81
82 n64_syscall_exit_work:
83         j       syscall_exit_work_partial
84
85 /* ------------------------------------------------------------------------ */
86
87 syscall_trace_entry:
88         SAVE_STATIC
89         sd      t2,PT_R1(sp)
90         move    a0, sp
91         li      a1, 0
92         jal     do_syscall_trace
93         ld      t2,PT_R1(sp)
94
95         ld      a0, PT_R4(sp)           # Restore argument registers
96         ld      a1, PT_R5(sp)
97         ld      a2, PT_R6(sp)
98         ld      a3, PT_R7(sp)
99         jalr    t2
100
101         li      t0, -EMAXERRNO - 1      # error?
102         sltu    t0, t0, v0
103         sd      t0, PT_R7(sp)           # set error flag
104         beqz    t0, 1f
105
106         negu    v0                      # error
107         sd      v0, PT_R0(sp)           # set flag for syscall restarting
108 1:      sd      v0, PT_R2(sp)           # result
109
110         j       syscall_exit
111
112 illegal_syscall:
113         /* This also isn't a 64-bit syscall, throw an error.  */
114         li      v0, ENOSYS                      # error
115         sd      v0, PT_R2(sp)
116         li      t0, 1                           # set error flag
117         sd      t0, PT_R7(sp)
118         j       syscall_exit
119         END(handle_sys64)
120
121         LEAF(mips_atomic_set)
122         andi    v0, a1, 3                       # must be word aligned
123         bnez    v0, bad_alignment
124
125         LONG_L  v1, TI_ADDR_LIMIT($28)          # in legal address range?
126         LONG_ADDIU      a0, a1, 4
127         or      a0, a0, a1
128         and     a0, a0, v1
129         bltz    a0, bad_address
130
131 #ifdef CONFIG_CPU_HAS_LLSC
132         /* Ok, this is the ll/sc case.  World is sane :-)  */
133 1:      ll      v0, (a1)
134         move    a0, a2
135 2:      sc      a0, (a1)
136         beqz    a0, 1b
137
138         .section __ex_table,"a"
139         PTR     1b, bad_stack
140         PTR     2b, bad_stack
141         .previous
142 #else
143         sw      a1, 16(sp)
144         sw      a2, 20(sp)
145
146         move    a0, sp
147         move    a2, a1
148         li      a1, 1
149         jal     do_page_fault
150
151         lw      a1, 16(sp)
152         lw      a2, 20(sp)
153
154         /*
155          * At this point the page should be readable and writable unless
156          * there was no more memory available.
157          */
158 1:      lw      v0, (a1)
159 2:      sw      a2, (a1)
160
161         .section __ex_table,"a"
162         PTR     1b, no_mem
163         PTR     2b, no_mem
164         .previous
165 #endif
166
167         sd      zero, PT_R7(sp)         # success
168         sd      v0, PT_R2(sp)           # result
169
170         /* Success, so skip usual error handling garbage.  */
171         LONG_L  a2, TI_FLAGS($28)       # syscall tracing enabled?
172         li      t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
173         and     t0, a2, t0
174         bnez    t0, 1f
175
176         b       syscall_exit
177
178 1:      SAVE_STATIC
179         move    a0, sp
180         li      a1, 1
181         jal     do_syscall_trace
182         j       syscall_exit
183
184 no_mem: li      v0, -ENOMEM
185         jr      ra
186
187 bad_address:
188         li      v0, -EFAULT
189         jr      ra
190
191 bad_alignment:
192         li      v0, -EINVAL
193         jr      ra
194         END(mips_atomic_set)
195
196         LEAF(sys_sysmips)
197         beq     a0, MIPS_ATOMIC_SET, mips_atomic_set
198         j       _sys_sysmips
199         END(sys_sysmips)
200
201         LEAF(sys_syscall)                       /* Quick'n'dirty ... */
202         move    v0, a0
203         move    a0, a1
204         move    a1, a2
205         move    a2, a3
206         move    a3, a4
207         move    a4, a5
208         move    a5, a6
209         j       __handle_sys64
210         END(sys_syscall)
211
212         .align  3
213 sys_call_table:
214         PTR     sys_read                        /* 5000 */
215         PTR     sys_write
216         PTR     sys_open
217         PTR     sys_close
218         PTR     sys_newstat
219         PTR     sys_newfstat                    /* 5005 */
220         PTR     sys_newlstat
221         PTR     sys_poll
222         PTR     sys_lseek
223         PTR     old_mmap
224         PTR     sys_mprotect                    /* 5010 */
225         PTR     sys_munmap
226         PTR     sys_brk
227         PTR     sys_rt_sigaction
228         PTR     sys_rt_sigprocmask
229         PTR     sys_ioctl                       /* 5015 */
230         PTR     sys_pread64
231         PTR     sys_pwrite64
232         PTR     sys_readv
233         PTR     sys_writev
234         PTR     sys_access                      /* 5020 */
235         PTR     sys_pipe
236         PTR     sys_select
237         PTR     sys_sched_yield
238         PTR     sys_mremap
239         PTR     sys_msync                       /* 5025 */
240         PTR     sys_mincore
241         PTR     sys_madvise
242         PTR     sys_shmget
243         PTR     sys_shmat
244         PTR     sys_shmctl                      /* 5030 */
245         PTR     sys_dup
246         PTR     sys_dup2
247         PTR     sys_pause
248         PTR     sys_nanosleep
249         PTR     sys_getitimer                   /* 5035 */
250         PTR     sys_setitimer
251         PTR     sys_alarm
252         PTR     sys_getpid
253         PTR     sys_sendfile64
254         PTR     sys_socket                      /* 5040 */
255         PTR     sys_connect
256         PTR     sys_accept
257         PTR     sys_sendto
258         PTR     sys_recvfrom
259         PTR     sys_sendmsg                     /* 5045 */
260         PTR     sys_recvmsg
261         PTR     sys_shutdown
262         PTR     sys_bind
263         PTR     sys_listen
264         PTR     sys_getsockname                 /* 5050 */
265         PTR     sys_getpeername
266         PTR     sys_socketpair
267         PTR     sys_setsockopt
268         PTR     sys_getsockopt
269         PTR     sys_clone                       /* 5055 */
270         PTR     sys_fork
271         PTR     sys_execve
272         PTR     sys_exit
273         PTR     sys_wait4
274         PTR     sys_kill                        /* 5060 */
275         PTR     sys_newuname
276         PTR     sys_semget
277         PTR     sys_semop
278         PTR     sys_semctl
279         PTR     sys_shmdt                       /* 5065 */
280         PTR     sys_msgget
281         PTR     sys_msgsnd
282         PTR     sys_msgrcv
283         PTR     sys_msgctl
284         PTR     sys_fcntl                       /* 5070 */
285         PTR     sys_flock
286         PTR     sys_fsync
287         PTR     sys_fdatasync
288         PTR     sys_truncate
289         PTR     sys_ftruncate                   /* 5075 */
290         PTR     sys_getdents
291         PTR     sys_getcwd
292         PTR     sys_chdir
293         PTR     sys_fchdir
294         PTR     sys_rename                      /* 5080 */
295         PTR     sys_mkdir
296         PTR     sys_rmdir
297         PTR     sys_creat
298         PTR     sys_link
299         PTR     sys_unlink                      /* 5085 */
300         PTR     sys_symlink
301         PTR     sys_readlink
302         PTR     sys_chmod
303         PTR     sys_fchmod
304         PTR     sys_chown                       /* 5090 */
305         PTR     sys_fchown
306         PTR     sys_lchown
307         PTR     sys_umask
308         PTR     sys_gettimeofday
309         PTR     sys_getrlimit                   /* 5095 */
310         PTR     sys_getrusage
311         PTR     sys_sysinfo
312         PTR     sys_times
313         PTR     sys_ptrace
314         PTR     sys_getuid                      /* 5100 */
315         PTR     sys_syslog
316         PTR     sys_getgid
317         PTR     sys_setuid
318         PTR     sys_setgid
319         PTR     sys_geteuid                     /* 5105 */
320         PTR     sys_getegid
321         PTR     sys_setpgid
322         PTR     sys_getppid
323         PTR     sys_getpgrp
324         PTR     sys_setsid                      /* 5110 */
325         PTR     sys_setreuid
326         PTR     sys_setregid
327         PTR     sys_getgroups
328         PTR     sys_setgroups
329         PTR     sys_setresuid                   /* 5115 */
330         PTR     sys_getresuid
331         PTR     sys_setresgid
332         PTR     sys_getresgid
333         PTR     sys_getpgid
334         PTR     sys_setfsuid                    /* 5120 */
335         PTR     sys_setfsgid
336         PTR     sys_getsid
337         PTR     sys_capget
338         PTR     sys_capset
339         PTR     sys_rt_sigpending               /* 5125 */
340         PTR     sys_rt_sigtimedwait
341         PTR     sys_rt_sigqueueinfo
342         PTR     sys_rt_sigsuspend
343         PTR     sys_sigaltstack
344         PTR     sys_utime                       /* 5130 */
345         PTR     sys_mknod
346         PTR     sys_personality
347         PTR     sys_ustat
348         PTR     sys_statfs
349         PTR     sys_fstatfs                     /* 5135 */
350         PTR     sys_sysfs
351         PTR     sys_getpriority
352         PTR     sys_setpriority
353         PTR     sys_sched_setparam
354         PTR     sys_sched_getparam              /* 5140 */
355         PTR     sys_sched_setscheduler
356         PTR     sys_sched_getscheduler
357         PTR     sys_sched_get_priority_max
358         PTR     sys_sched_get_priority_min
359         PTR     sys_sched_rr_get_interval       /* 5145 */
360         PTR     sys_mlock
361         PTR     sys_munlock
362         PTR     sys_mlockall
363         PTR     sys_munlockall
364         PTR     sys_vhangup                     /* 5150 */
365         PTR     sys_pivot_root
366         PTR     sys_sysctl
367         PTR     sys_prctl
368         PTR     sys_adjtimex
369         PTR     sys_setrlimit                   /* 5155 */
370         PTR     sys_chroot
371         PTR     sys_sync
372         PTR     sys_acct
373         PTR     sys_settimeofday
374         PTR     sys_mount                       /* 5160 */
375         PTR     sys_umount
376         PTR     sys_swapon
377         PTR     sys_swapoff
378         PTR     sys_reboot
379         PTR     sys_sethostname                 /* 5165 */
380         PTR     sys_setdomainname
381         PTR     sys_ni_syscall                  /* was create_module */
382         PTR     sys_init_module
383         PTR     sys_delete_module
384         PTR     sys_ni_syscall                  /* 5170, was get_kernel_syms */
385         PTR     sys_ni_syscall                  /* was query_module */
386         PTR     sys_quotactl
387         PTR     sys_nfsservctl
388         PTR     sys_ni_syscall                  /* res. for getpmsg */
389         PTR     sys_ni_syscall                  /* 5175  for putpmsg */
390         PTR     sys_ni_syscall                  /* res. for afs_syscall */
391         PTR     sys_ni_syscall                  /* res. for security */
392         PTR     sys_gettid
393         PTR     sys_readahead
394         PTR     sys_setxattr                    /* 5180 */
395         PTR     sys_lsetxattr
396         PTR     sys_fsetxattr
397         PTR     sys_getxattr
398         PTR     sys_lgetxattr
399         PTR     sys_fgetxattr                   /* 5185 */
400         PTR     sys_listxattr
401         PTR     sys_llistxattr
402         PTR     sys_flistxattr
403         PTR     sys_removexattr
404         PTR     sys_lremovexattr                /* 5190 */
405         PTR     sys_fremovexattr
406         PTR     sys_tkill
407         PTR     sys_ni_syscall
408         PTR     sys_futex
409         PTR     sys_sched_setaffinity           /* 5195 */
410         PTR     sys_sched_getaffinity
411         PTR     sys_cacheflush
412         PTR     sys_cachectl
413         PTR     sys_sysmips
414         PTR     sys_io_setup                    /* 5200 */
415         PTR     sys_io_destroy
416         PTR     sys_io_getevents
417         PTR     sys_io_submit
418         PTR     sys_io_cancel
419         PTR     sys_exit_group                  /* 5205 */
420         PTR     sys_lookup_dcookie
421         PTR     sys_epoll_create
422         PTR     sys_epoll_ctl
423         PTR     sys_epoll_wait
424         PTR     sys_remap_file_pages            /* 5210 */
425         PTR     sys_rt_sigreturn
426         PTR     sys_set_tid_address
427         PTR     sys_restart_syscall
428         PTR     sys_semtimedop
429         PTR     sys_fadvise64_64                /* 5215 */
430         PTR     sys_timer_create
431         PTR     sys_timer_settime
432         PTR     sys_timer_gettime
433         PTR     sys_timer_getoverrun
434         PTR     sys_timer_delete                /* 5220 */
435         PTR     sys_clock_settime
436         PTR     sys_clock_gettime
437         PTR     sys_clock_getres
438         PTR     sys_clock_nanosleep
439         PTR     sys_tgkill                      /* 5225 */
440         PTR     sys_utimes
441         PTR     sys_ni_syscall                  /* sys_mbind */
442         PTR     sys_ni_syscall                  /* sys_get_mempolicy */
443         PTR     sys_ni_syscall                  /* sys_set_mempolicy */
444         PTR     sys_mq_open                     /* 5230 */
445         PTR     sys_mq_unlink
446         PTR     sys_mq_timedsend
447         PTR     sys_mq_timedreceive
448         PTR     sys_mq_notify
449         PTR     sys_mq_getsetattr               /* 5235 */