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