xref: /linux/arch/mips/kernel/scall32-o32.S (revision c4ee0af3fa0dc65f690fc908f02b8355f9576ea0)
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 */
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/isadep.h>
18#include <asm/sysmips.h>
19#include <asm/thread_info.h>
20#include <asm/unistd.h>
21#include <asm/war.h>
22#include <asm/asm-offsets.h>
23
24/* Highest syscall used of any syscall flavour */
25#define MAX_SYSCALL_NO	__NR_O32_Linux + __NR_O32_Linux_syscalls
26
27	.align	5
28NESTED(handle_sys, PT_SIZE, sp)
29	.set	noat
30	SAVE_SOME
31	TRACE_IRQS_ON_RELOAD
32	STI
33	.set	at
34
35	lw	t1, PT_EPC(sp)		# skip syscall on return
36
37	subu	v0, v0, __NR_O32_Linux	# check syscall number
38	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
39	addiu	t1, 4			# skip to next instruction
40	sw	t1, PT_EPC(sp)
41	beqz	t0, illegal_syscall
42
43	sll	t0, v0, 2
44	la	t1, sys_call_table
45	addu	t1, t0
46	lw	t2, (t1)		# syscall routine
47	beqz	t2, illegal_syscall
48
49	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
50
51	/*
52	 * More than four arguments.  Try to deal with it by copying the
53	 * stack arguments from the user stack to the kernel stack.
54	 * This Sucks (TM).
55	 */
56	lw	t0, PT_R29(sp)		# get old user stack pointer
57
58	/*
59	 * We intentionally keep the kernel stack a little below the top of
60	 * userspace so we don't have to do a slower byte accurate check here.
61	 */
62	lw	t5, TI_ADDR_LIMIT($28)
63	addu	t4, t0, 32
64	and	t5, t4
65	bltz	t5, bad_stack		# -> sp is bad
66
67	/*
68	 * Ok, copy the args from the luser stack to the kernel stack.
69	 * t3 is the precomputed number of instruction bytes needed to
70	 * load or store arguments 6-8.
71	 */
72
73	.set    push
74	.set    noreorder
75	.set	nomacro
76
771:	lw	t5, 16(t0)		# argument #5 from usp
784:	lw	t6, 20(t0)		# argument #6 from usp
793:	lw	t7, 24(t0)		# argument #7 from usp
802:	lw	t8, 28(t0)		# argument #8 from usp
81
82	sw	t5, 16(sp)		# argument #5 to ksp
83	sw	t6, 20(sp)		# argument #6 to ksp
84	sw	t7, 24(sp)		# argument #7 to ksp
85	sw	t8, 28(sp)		# argument #8 to ksp
86	.set	pop
87
88	.section __ex_table,"a"
89	PTR	1b,bad_stack
90	PTR	2b,bad_stack
91	PTR	3b,bad_stack
92	PTR	4b,bad_stack
93	.previous
94
95	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
96	li	t1, _TIF_WORK_SYSCALL_ENTRY
97	and	t0, t1
98	bnez	t0, syscall_trace_entry # -> yes
99
100	jalr	t2			# Do The Real Thing (TM)
101
102	li	t0, -EMAXERRNO - 1	# error?
103	sltu	t0, t0, v0
104	sw	t0, PT_R7(sp)		# set error flag
105	beqz	t0, 1f
106
107	lw	t1, PT_R2(sp)		# syscall number
108	negu	v0			# error
109	sw	t1, PT_R0(sp)		# save it for syscall restarting
1101:	sw	v0, PT_R2(sp)		# result
111
112o32_syscall_exit:
113	j	syscall_exit_partial
114
115/* ------------------------------------------------------------------------ */
116
117syscall_trace_entry:
118	SAVE_STATIC
119	move	s0, t2
120	move	a0, sp
121	jal	syscall_trace_enter
122
123	move	t0, s0
124	RESTORE_STATIC
125	lw	a0, PT_R4(sp)		# Restore argument registers
126	lw	a1, PT_R5(sp)
127	lw	a2, PT_R6(sp)
128	lw	a3, PT_R7(sp)
129	jalr	t0
130
131	li	t0, -EMAXERRNO - 1	# error?
132	sltu	t0, t0, v0
133	sw	t0, PT_R7(sp)		# set error flag
134	beqz	t0, 1f
135
136	lw	t1, PT_R2(sp)		# syscall number
137	negu	v0			# error
138	sw	t1, PT_R0(sp)		# save it for syscall restarting
1391:	sw	v0, PT_R2(sp)		# result
140
141	j	syscall_exit
142
143/* ------------------------------------------------------------------------ */
144
145	/*
146	 * The stackpointer for a call with more than 4 arguments is bad.
147	 * We probably should handle this case a bit more drastic.
148	 */
149bad_stack:
150	li	v0, EFAULT
151	sw	v0, PT_R2(sp)
152	li	t0, 1				# set error flag
153	sw	t0, PT_R7(sp)
154	j	o32_syscall_exit
155
156	/*
157	 * The system call does not exist in this kernel
158	 */
159illegal_syscall:
160	li	v0, ENOSYS			# error
161	sw	v0, PT_R2(sp)
162	li	t0, 1				# set error flag
163	sw	t0, PT_R7(sp)
164	j	o32_syscall_exit
165	END(handle_sys)
166
167	LEAF(sys_syscall)
168	subu	t0, a0, __NR_O32_Linux	# check syscall number
169	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
170	beqz	t0, einval		# do not recurse
171	sll	t1, t0, 2
172	beqz	v0, einval
173	lw	t2, sys_call_table(t1)		# syscall routine
174
175	/* Some syscalls like execve get their arguments from struct pt_regs
176	   and claim zero arguments in the syscall table. Thus we have to
177	   assume the worst case and shuffle around all potential arguments.
178	   If you want performance, don't use indirect syscalls. */
179
180	move	a0, a1				# shift argument registers
181	move	a1, a2
182	move	a2, a3
183	lw	a3, 16(sp)
184	lw	t4, 20(sp)
185	lw	t5, 24(sp)
186	lw	t6, 28(sp)
187	sw	t4, 16(sp)
188	sw	t5, 20(sp)
189	sw	t6, 24(sp)
190	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some
191	sw	a1, PT_R5(sp)			# syscalls expect them there
192	sw	a2, PT_R6(sp)
193	sw	a3, PT_R7(sp)
194	sw	a3, PT_R26(sp)			# update a3 for syscall restarting
195	jr	t2
196	/* Unreached */
197
198einval: li	v0, -ENOSYS
199	jr	ra
200	END(sys_syscall)
201
202	.align	2
203	.type	sys_call_table, @object
204EXPORT(sys_call_table)
205	PTR	sys_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	sys_execve
217	PTR	sys_chdir
218	PTR	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	sys_stime			/* 4025 */
231	PTR	sys_ptrace
232	PTR	sys_alarm
233	PTR	sys_ni_syscall			/* was sys_fstat */
234	PTR	sys_pause
235	PTR	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	sysm_pipe
248	PTR	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	sys_ioctl
260	PTR	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	sys_ustat
268	PTR	sys_dup2
269	PTR	sys_getppid
270	PTR	sys_getpgrp			/* 4065 */
271	PTR	sys_setsid
272	PTR	sys_sigaction
273	PTR	sys_sgetmask
274	PTR	sys_ssetmask
275	PTR	sys_setreuid			/* 4070 */
276	PTR	sys_setregid
277	PTR	sys_sigsuspend
278	PTR	sys_sigpending
279	PTR	sys_sethostname
280	PTR	sys_setrlimit			/* 4075 */
281	PTR	sys_getrlimit
282	PTR	sys_getrusage
283	PTR	sys_gettimeofday
284	PTR	sys_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	sys_old_readdir
295	PTR	sys_mips_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	sys_statfs
305	PTR	sys_fstatfs			/* 4100 */
306	PTR	sys_ni_syscall			/* was ioperm(2) */
307	PTR	sys_socketcall
308	PTR	sys_syslog
309	PTR	sys_setitimer
310	PTR	sys_getitimer			/* 4105 */
311	PTR	sys_newstat
312	PTR	sys_newlstat
313	PTR	sys_newfstat
314	PTR	sys_uname
315	PTR	sys_ni_syscall			/* 4110 was iopl(2) */
316	PTR	sys_vhangup
317	PTR	sys_ni_syscall			/* was sys_idle() */
318	PTR	sys_ni_syscall			/* was sys_vm86 */
319	PTR	sys_wait4
320	PTR	sys_swapoff			/* 4115 */
321	PTR	sys_sysinfo
322	PTR	sys_ipc
323	PTR	sys_fsync
324	PTR	sys_sigreturn
325	PTR	__sys_clone			/* 4120 */
326	PTR	sys_setdomainname
327	PTR	sys_newuname
328	PTR	sys_ni_syscall			/* sys_modify_ldt */
329	PTR	sys_adjtimex
330	PTR	sys_mprotect			/* 4125 */
331	PTR	sys_sigprocmask
332	PTR	sys_ni_syscall			/* was create_module */
333	PTR	sys_init_module
334	PTR	sys_delete_module
335	PTR	sys_ni_syscall			/* 4130 was 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	sys_personality
342	PTR	sys_ni_syscall			/* for afs_syscall */
343	PTR	sys_setfsuid
344	PTR	sys_setfsgid
345	PTR	sys_llseek			/* 4140 */
346	PTR	sys_getdents
347	PTR	sys_select
348	PTR	sys_flock
349	PTR	sys_msync
350	PTR	sys_readv			/* 4145 */
351	PTR	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	sys_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	sys_sched_rr_get_interval	/* 4165 */
371	PTR	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	sys_recvmsg
383	PTR	sys_send
384	PTR	sys_sendmsg
385	PTR	sys_sendto			/* 4180 */
386	PTR	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 sys_query_module */
393	PTR	sys_poll
394	PTR	sys_ni_syscall			/* was nfsservctl */
395	PTR	sys_setresgid			/* 4190 */
396	PTR	sys_getresgid
397	PTR	sys_prctl
398	PTR	sys_rt_sigreturn
399	PTR	sys_rt_sigaction
400	PTR	sys_rt_sigprocmask		/* 4195 */
401	PTR	sys_rt_sigpending
402	PTR	sys_rt_sigtimedwait
403	PTR	sys_rt_sigqueueinfo
404	PTR	sys_rt_sigsuspend
405	PTR	sys_pread64			/* 4200 */
406	PTR	sys_pwrite64
407	PTR	sys_chown
408	PTR	sys_getcwd
409	PTR	sys_capget
410	PTR	sys_capset			/* 4205 */
411	PTR	sys_sigaltstack
412	PTR	sys_sendfile
413	PTR	sys_ni_syscall
414	PTR	sys_ni_syscall
415	PTR	sys_mips_mmap2			/* 4210 */
416	PTR	sys_truncate64
417	PTR	sys_ftruncate64
418	PTR	sys_stat64
419	PTR	sys_lstat64
420	PTR	sys_fstat64			/* 4215 */
421	PTR	sys_pivot_root
422	PTR	sys_mincore
423	PTR	sys_madvise
424	PTR	sys_getdents64
425	PTR	sys_fcntl64			/* 4220 */
426	PTR	sys_ni_syscall
427	PTR	sys_gettid
428	PTR	sys_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	sys_futex
444#ifdef CONFIG_MIPS_MT_FPAFF
445	/*
446	 * For FPU affinity scheduling on MIPS MT processors, we need to
447	 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
448	 * in kernel/sched/core.c.  Considered only temporary we only support
449	 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
450	 * atm.
451	 */
452	PTR	mipsmt_sys_sched_setaffinity
453	PTR	mipsmt_sys_sched_getaffinity
454#else
455	PTR	sys_sched_setaffinity
456	PTR	sys_sched_getaffinity		/* 4240 */
457#endif /* CONFIG_MIPS_MT_FPAFF */
458	PTR	sys_io_setup
459	PTR	sys_io_destroy
460	PTR	sys_io_getevents
461	PTR	sys_io_submit
462	PTR	sys_io_cancel			/* 4245 */
463	PTR	sys_exit_group
464	PTR	sys_lookup_dcookie
465	PTR	sys_epoll_create
466	PTR	sys_epoll_ctl
467	PTR	sys_epoll_wait			/* 4250 */
468	PTR	sys_remap_file_pages
469	PTR	sys_set_tid_address
470	PTR	sys_restart_syscall
471	PTR	sys_fadvise64_64
472	PTR	sys_statfs64			/* 4255 */
473	PTR	sys_fstatfs64
474	PTR	sys_timer_create
475	PTR	sys_timer_settime
476	PTR	sys_timer_gettime
477	PTR	sys_timer_getoverrun		/* 4260 */
478	PTR	sys_timer_delete
479	PTR	sys_clock_settime
480	PTR	sys_clock_gettime
481	PTR	sys_clock_getres
482	PTR	sys_clock_nanosleep		/* 4265 */
483	PTR	sys_tgkill
484	PTR	sys_utimes
485	PTR	sys_mbind
486	PTR	sys_ni_syscall			/* sys_get_mempolicy */
487	PTR	sys_ni_syscall			/* 4270 sys_set_mempolicy */
488	PTR	sys_mq_open
489	PTR	sys_mq_unlink
490	PTR	sys_mq_timedsend
491	PTR	sys_mq_timedreceive
492	PTR	sys_mq_notify			/* 4275 */
493	PTR	sys_mq_getsetattr
494	PTR	sys_ni_syscall			/* sys_vserver */
495	PTR	sys_waitid
496	PTR	sys_ni_syscall			/* available, was setaltroot */
497	PTR	sys_add_key			/* 4280 */
498	PTR	sys_request_key
499	PTR	sys_keyctl
500	PTR	sys_set_thread_area
501	PTR	sys_inotify_init
502	PTR	sys_inotify_add_watch		/* 4285 */
503	PTR	sys_inotify_rm_watch
504	PTR	sys_migrate_pages
505	PTR	sys_openat
506	PTR	sys_mkdirat
507	PTR	sys_mknodat			/* 4290 */
508	PTR	sys_fchownat
509	PTR	sys_futimesat
510	PTR	sys_fstatat64
511	PTR	sys_unlinkat
512	PTR	sys_renameat			/* 4295 */
513	PTR	sys_linkat
514	PTR	sys_symlinkat
515	PTR	sys_readlinkat
516	PTR	sys_fchmodat
517	PTR	sys_faccessat			/* 4300 */
518	PTR	sys_pselect6
519	PTR	sys_ppoll
520	PTR	sys_unshare
521	PTR	sys_splice
522	PTR	sys_sync_file_range		/* 4305 */
523	PTR	sys_tee
524	PTR	sys_vmsplice
525	PTR	sys_move_pages
526	PTR	sys_set_robust_list
527	PTR	sys_get_robust_list		/* 4310 */
528	PTR	sys_kexec_load
529	PTR	sys_getcpu
530	PTR	sys_epoll_pwait
531	PTR	sys_ioprio_set
532	PTR	sys_ioprio_get			/* 4315 */
533	PTR	sys_utimensat
534	PTR	sys_signalfd
535	PTR	sys_ni_syscall			/* was timerfd */
536	PTR	sys_eventfd
537	PTR	sys_fallocate			/* 4320 */
538	PTR	sys_timerfd_create
539	PTR	sys_timerfd_gettime
540	PTR	sys_timerfd_settime
541	PTR	sys_signalfd4
542	PTR	sys_eventfd2			/* 4325 */
543	PTR	sys_epoll_create1
544	PTR	sys_dup3
545	PTR	sys_pipe2
546	PTR	sys_inotify_init1
547	PTR	sys_preadv			/* 4330 */
548	PTR	sys_pwritev
549	PTR	sys_rt_tgsigqueueinfo
550	PTR	sys_perf_event_open
551	PTR	sys_accept4
552	PTR	sys_recvmmsg			/* 4335 */
553	PTR	sys_fanotify_init
554	PTR	sys_fanotify_mark
555	PTR	sys_prlimit64
556	PTR	sys_name_to_handle_at
557	PTR	sys_open_by_handle_at		/* 4340 */
558	PTR	sys_clock_adjtime
559	PTR	sys_syncfs
560	PTR	sys_sendmmsg
561	PTR	sys_setns
562	PTR	sys_process_vm_readv		/* 4345 */
563	PTR	sys_process_vm_writev
564	PTR	sys_kcmp
565	PTR	sys_finit_module
566