writeback: Fix performance regression in wb_over_bg_thresh()
[deliverable/linux.git] / arch / mips / kernel / scall32-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-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org>
7 * Copyright (C) 2001 MIPS Technologies, Inc.
8 * Copyright (C) 2004 Thiemo Seufer
9 * Copyright (C) 2014 Imagination Technologies Ltd.
10 */
11 #include <linux/errno.h>
12 #include <asm/asm.h>
13 #include <asm/asmmacro.h>
14 #include <asm/irqflags.h>
15 #include <asm/mipsregs.h>
16 #include <asm/regdef.h>
17 #include <asm/stackframe.h>
18 #include <asm/isadep.h>
19 #include <asm/sysmips.h>
20 #include <asm/thread_info.h>
21 #include <asm/unistd.h>
22 #include <asm/war.h>
23 #include <asm/asm-offsets.h>
24
25 /* Highest syscall used of any syscall flavour */
26 #define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
27
28 .align 5
29 NESTED(handle_sys, PT_SIZE, sp)
30 .set noat
31 SAVE_SOME
32 TRACE_IRQS_ON_RELOAD
33 STI
34 .set at
35
36 lw t1, PT_EPC(sp) # skip syscall on return
37
38 subu v0, v0, __NR_O32_Linux # check syscall number
39 addiu t1, 4 # skip to next instruction
40 sw t1, PT_EPC(sp)
41
42 sw a3, PT_R26(sp) # save a3 for syscall restarting
43
44 /*
45 * More than four arguments. Try to deal with it by copying the
46 * stack arguments from the user stack to the kernel stack.
47 * This Sucks (TM).
48 */
49 lw t0, PT_R29(sp) # get old user stack pointer
50
51 /*
52 * We intentionally keep the kernel stack a little below the top of
53 * userspace so we don't have to do a slower byte accurate check here.
54 */
55 lw t5, TI_ADDR_LIMIT($28)
56 addu t4, t0, 32
57 and t5, t4
58 bltz t5, bad_stack # -> sp is bad
59
60 /*
61 * Ok, copy the args from the luser stack to the kernel stack.
62 */
63
64 .set push
65 .set noreorder
66 .set nomacro
67
68 load_a4: user_lw(t5, 16(t0)) # argument #5 from usp
69 load_a5: user_lw(t6, 20(t0)) # argument #6 from usp
70 load_a6: user_lw(t7, 24(t0)) # argument #7 from usp
71 load_a7: user_lw(t8, 28(t0)) # argument #8 from usp
72 loads_done:
73
74 sw t5, 16(sp) # argument #5 to ksp
75 sw t6, 20(sp) # argument #6 to ksp
76 sw t7, 24(sp) # argument #7 to ksp
77 sw t8, 28(sp) # argument #8 to ksp
78 .set pop
79
80 .section __ex_table,"a"
81 PTR load_a4, bad_stack_a4
82 PTR load_a5, bad_stack_a5
83 PTR load_a6, bad_stack_a6
84 PTR load_a7, bad_stack_a7
85 .previous
86
87 lw t0, TI_FLAGS($28) # syscall tracing enabled?
88 li t1, _TIF_WORK_SYSCALL_ENTRY
89 and t0, t1
90 bnez t0, syscall_trace_entry # -> yes
91 syscall_common:
92 sltiu t0, v0, __NR_O32_Linux_syscalls + 1
93 beqz t0, illegal_syscall
94
95 sll t0, v0, 2
96 la t1, sys_call_table
97 addu t1, t0
98 lw t2, (t1) # syscall routine
99
100 beqz t2, illegal_syscall
101
102 jalr t2 # Do The Real Thing (TM)
103
104 li t0, -EMAXERRNO - 1 # error?
105 sltu t0, t0, v0
106 sw t0, PT_R7(sp) # set error flag
107 beqz t0, 1f
108
109 lw t1, PT_R2(sp) # syscall number
110 negu v0 # error
111 sw t1, PT_R0(sp) # save it for syscall restarting
112 1: sw v0, PT_R2(sp) # result
113
114 o32_syscall_exit:
115 j syscall_exit_partial
116
117 /* ------------------------------------------------------------------------ */
118
119 syscall_trace_entry:
120 SAVE_STATIC
121 move s0, v0
122 move a0, sp
123
124 /*
125 * syscall number is in v0 unless we called syscall(__NR_###)
126 * where the real syscall number is in a0
127 */
128 addiu a1, v0, __NR_O32_Linux
129 bnez v0, 1f /* __NR_syscall at offset 0 */
130 lw a1, PT_R4(sp)
131
132 1: jal syscall_trace_enter
133
134 bltz v0, 1f # seccomp failed? Skip syscall
135
136 move v0, s0 # restore syscall
137
138 RESTORE_STATIC
139 lw a0, PT_R4(sp) # Restore argument registers
140 lw a1, PT_R5(sp)
141 lw a2, PT_R6(sp)
142 lw a3, PT_R7(sp)
143 j syscall_common
144
145 1: j syscall_exit
146
147 /* ------------------------------------------------------------------------ */
148
149 /*
150 * Our open-coded access area sanity test for the stack pointer
151 * failed. We probably should handle this case a bit more drastic.
152 */
153 bad_stack:
154 li v0, EFAULT
155 sw v0, PT_R2(sp)
156 li t0, 1 # set error flag
157 sw t0, PT_R7(sp)
158 j o32_syscall_exit
159
160 bad_stack_a4:
161 li t5, 0
162 b load_a5
163
164 bad_stack_a5:
165 li t6, 0
166 b load_a6
167
168 bad_stack_a6:
169 li t7, 0
170 b load_a7
171
172 bad_stack_a7:
173 li t8, 0
174 b loads_done
175
176 /*
177 * The system call does not exist in this kernel
178 */
179 illegal_syscall:
180 li v0, ENOSYS # error
181 sw v0, PT_R2(sp)
182 li t0, 1 # set error flag
183 sw t0, PT_R7(sp)
184 j o32_syscall_exit
185 END(handle_sys)
186
187 LEAF(sys_syscall)
188 subu t0, a0, __NR_O32_Linux # check syscall number
189 sltiu v0, t0, __NR_O32_Linux_syscalls + 1
190 beqz t0, einval # do not recurse
191 sll t1, t0, 2
192 beqz v0, einval
193 lw t2, sys_call_table(t1) # syscall routine
194 sw a0, PT_R2(sp) # call routine directly on restart
195
196 /* Some syscalls like execve get their arguments from struct pt_regs
197 and claim zero arguments in the syscall table. Thus we have to
198 assume the worst case and shuffle around all potential arguments.
199 If you want performance, don't use indirect syscalls. */
200
201 move a0, a1 # shift argument registers
202 move a1, a2
203 move a2, a3
204 lw a3, 16(sp)
205 lw t4, 20(sp)
206 lw t5, 24(sp)
207 lw t6, 28(sp)
208 sw t4, 16(sp)
209 sw t5, 20(sp)
210 sw t6, 24(sp)
211 sw a0, PT_R4(sp) # .. and push back a0 - a3, some
212 sw a1, PT_R5(sp) # syscalls expect them there
213 sw a2, PT_R6(sp)
214 sw a3, PT_R7(sp)
215 sw a3, PT_R26(sp) # update a3 for syscall restarting
216 jr t2
217 /* Unreached */
218
219 einval: li v0, -ENOSYS
220 jr ra
221 END(sys_syscall)
222
223 .align 2
224 .type sys_call_table, @object
225 EXPORT(sys_call_table)
226 PTR sys_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 sys_execve
238 PTR sys_chdir
239 PTR 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 sys_stime /* 4025 */
252 PTR sys_ptrace
253 PTR sys_alarm
254 PTR sys_ni_syscall /* was sys_fstat */
255 PTR sys_pause
256 PTR 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 sysm_pipe
269 PTR 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 sys_ioctl
281 PTR 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 sys_ustat
289 PTR sys_dup2
290 PTR sys_getppid
291 PTR sys_getpgrp /* 4065 */
292 PTR sys_setsid
293 PTR sys_sigaction
294 PTR sys_sgetmask
295 PTR sys_ssetmask
296 PTR sys_setreuid /* 4070 */
297 PTR sys_setregid
298 PTR sys_sigsuspend
299 PTR sys_sigpending
300 PTR sys_sethostname
301 PTR sys_setrlimit /* 4075 */
302 PTR sys_getrlimit
303 PTR sys_getrusage
304 PTR sys_gettimeofday
305 PTR sys_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 sys_old_readdir
316 PTR sys_mips_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 sys_statfs
326 PTR sys_fstatfs /* 4100 */
327 PTR sys_ni_syscall /* was ioperm(2) */
328 PTR sys_socketcall
329 PTR sys_syslog
330 PTR sys_setitimer
331 PTR sys_getitimer /* 4105 */
332 PTR sys_newstat
333 PTR sys_newlstat
334 PTR sys_newfstat
335 PTR sys_uname
336 PTR sys_ni_syscall /* 4110 was iopl(2) */
337 PTR sys_vhangup
338 PTR sys_ni_syscall /* was sys_idle() */
339 PTR sys_ni_syscall /* was sys_vm86 */
340 PTR sys_wait4
341 PTR sys_swapoff /* 4115 */
342 PTR sys_sysinfo
343 PTR sys_ipc
344 PTR sys_fsync
345 PTR sys_sigreturn
346 PTR __sys_clone /* 4120 */
347 PTR sys_setdomainname
348 PTR sys_newuname
349 PTR sys_ni_syscall /* sys_modify_ldt */
350 PTR sys_adjtimex
351 PTR sys_mprotect /* 4125 */
352 PTR sys_sigprocmask
353 PTR sys_ni_syscall /* was create_module */
354 PTR sys_init_module
355 PTR sys_delete_module
356 PTR sys_ni_syscall /* 4130 was 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 sys_personality
363 PTR sys_ni_syscall /* for afs_syscall */
364 PTR sys_setfsuid
365 PTR sys_setfsgid
366 PTR sys_llseek /* 4140 */
367 PTR sys_getdents
368 PTR sys_select
369 PTR sys_flock
370 PTR sys_msync
371 PTR sys_readv /* 4145 */
372 PTR 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 sys_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 sys_sched_rr_get_interval /* 4165 */
392 PTR 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 sys_recvmsg
404 PTR sys_send
405 PTR sys_sendmsg
406 PTR sys_sendto /* 4180 */
407 PTR 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 sys_query_module */
414 PTR sys_poll
415 PTR sys_ni_syscall /* was nfsservctl */
416 PTR sys_setresgid /* 4190 */
417 PTR sys_getresgid
418 PTR sys_prctl
419 PTR sys_rt_sigreturn
420 PTR sys_rt_sigaction
421 PTR sys_rt_sigprocmask /* 4195 */
422 PTR sys_rt_sigpending
423 PTR sys_rt_sigtimedwait
424 PTR sys_rt_sigqueueinfo
425 PTR sys_rt_sigsuspend
426 PTR sys_pread64 /* 4200 */
427 PTR sys_pwrite64
428 PTR sys_chown
429 PTR sys_getcwd
430 PTR sys_capget
431 PTR sys_capset /* 4205 */
432 PTR sys_sigaltstack
433 PTR sys_sendfile
434 PTR sys_ni_syscall
435 PTR sys_ni_syscall
436 PTR sys_mips_mmap2 /* 4210 */
437 PTR sys_truncate64
438 PTR sys_ftruncate64
439 PTR sys_stat64
440 PTR sys_lstat64
441 PTR sys_fstat64 /* 4215 */
442 PTR sys_pivot_root
443 PTR sys_mincore
444 PTR sys_madvise
445 PTR sys_getdents64
446 PTR sys_fcntl64 /* 4220 */
447 PTR sys_ni_syscall
448 PTR sys_gettid
449 PTR sys_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 sys_futex
465 #ifdef CONFIG_MIPS_MT_FPAFF
466 /*
467 * For FPU affinity scheduling on MIPS MT processors, we need to
468 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
469 * in kernel/sched/core.c. Considered only temporary we only support
470 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
471 * atm.
472 */
473 PTR mipsmt_sys_sched_setaffinity
474 PTR mipsmt_sys_sched_getaffinity
475 #else
476 PTR sys_sched_setaffinity
477 PTR sys_sched_getaffinity /* 4240 */
478 #endif /* CONFIG_MIPS_MT_FPAFF */
479 PTR sys_io_setup
480 PTR sys_io_destroy
481 PTR sys_io_getevents
482 PTR sys_io_submit
483 PTR sys_io_cancel /* 4245 */
484 PTR sys_exit_group
485 PTR sys_lookup_dcookie
486 PTR sys_epoll_create
487 PTR sys_epoll_ctl
488 PTR sys_epoll_wait /* 4250 */
489 PTR sys_remap_file_pages
490 PTR sys_set_tid_address
491 PTR sys_restart_syscall
492 PTR sys_fadvise64_64
493 PTR sys_statfs64 /* 4255 */
494 PTR sys_fstatfs64
495 PTR sys_timer_create
496 PTR sys_timer_settime
497 PTR sys_timer_gettime
498 PTR sys_timer_getoverrun /* 4260 */
499 PTR sys_timer_delete
500 PTR sys_clock_settime
501 PTR sys_clock_gettime
502 PTR sys_clock_getres
503 PTR sys_clock_nanosleep /* 4265 */
504 PTR sys_tgkill
505 PTR sys_utimes
506 PTR sys_mbind
507 PTR sys_get_mempolicy
508 PTR sys_set_mempolicy /* 4270 */
509 PTR sys_mq_open
510 PTR sys_mq_unlink
511 PTR sys_mq_timedsend
512 PTR sys_mq_timedreceive
513 PTR sys_mq_notify /* 4275 */
514 PTR sys_mq_getsetattr
515 PTR sys_ni_syscall /* sys_vserver */
516 PTR sys_waitid
517 PTR sys_ni_syscall /* available, was setaltroot */
518 PTR sys_add_key /* 4280 */
519 PTR sys_request_key
520 PTR sys_keyctl
521 PTR sys_set_thread_area
522 PTR sys_inotify_init
523 PTR sys_inotify_add_watch /* 4285 */
524 PTR sys_inotify_rm_watch
525 PTR sys_migrate_pages
526 PTR sys_openat
527 PTR sys_mkdirat
528 PTR sys_mknodat /* 4290 */
529 PTR sys_fchownat
530 PTR sys_futimesat
531 PTR sys_fstatat64
532 PTR sys_unlinkat
533 PTR sys_renameat /* 4295 */
534 PTR sys_linkat
535 PTR sys_symlinkat
536 PTR sys_readlinkat
537 PTR sys_fchmodat
538 PTR sys_faccessat /* 4300 */
539 PTR sys_pselect6
540 PTR sys_ppoll
541 PTR sys_unshare
542 PTR sys_splice
543 PTR sys_sync_file_range /* 4305 */
544 PTR sys_tee
545 PTR sys_vmsplice
546 PTR sys_move_pages
547 PTR sys_set_robust_list
548 PTR sys_get_robust_list /* 4310 */
549 PTR sys_kexec_load
550 PTR sys_getcpu
551 PTR sys_epoll_pwait
552 PTR sys_ioprio_set
553 PTR sys_ioprio_get /* 4315 */
554 PTR sys_utimensat
555 PTR sys_signalfd
556 PTR sys_ni_syscall /* was timerfd */
557 PTR sys_eventfd
558 PTR sys_fallocate /* 4320 */
559 PTR sys_timerfd_create
560 PTR sys_timerfd_gettime
561 PTR sys_timerfd_settime
562 PTR sys_signalfd4
563 PTR sys_eventfd2 /* 4325 */
564 PTR sys_epoll_create1
565 PTR sys_dup3
566 PTR sys_pipe2
567 PTR sys_inotify_init1
568 PTR sys_preadv /* 4330 */
569 PTR sys_pwritev
570 PTR sys_rt_tgsigqueueinfo
571 PTR sys_perf_event_open
572 PTR sys_accept4
573 PTR sys_recvmmsg /* 4335 */
574 PTR sys_fanotify_init
575 PTR sys_fanotify_mark
576 PTR sys_prlimit64
577 PTR sys_name_to_handle_at
578 PTR sys_open_by_handle_at /* 4340 */
579 PTR sys_clock_adjtime
580 PTR sys_syncfs
581 PTR sys_sendmmsg
582 PTR sys_setns
583 PTR sys_process_vm_readv /* 4345 */
584 PTR sys_process_vm_writev
585 PTR sys_kcmp
586 PTR sys_finit_module
587 PTR sys_sched_setattr
588 PTR sys_sched_getattr /* 4350 */
589 PTR sys_renameat2
590 PTR sys_seccomp
591 PTR sys_getrandom
592 PTR sys_memfd_create
593 PTR sys_bpf /* 4355 */
594 PTR sys_execveat
595 PTR sys_userfaultfd
596 PTR sys_membarrier
597 PTR sys_mlock2
598 PTR sys_copy_file_range /* 4360 */
This page took 0.043888 seconds and 5 git commands to generate.