xref: /openbmc/linux/arch/mips/kernel/scall32-o32.S (revision e23feb16)
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, 3
44	la	t1, sys_call_table
45	addu	t1, t0
46	lw	t2, (t1)		# syscall routine
47	lw	t3, 4(t1)		# >= 0 if we need stack arguments
48	beqz	t2, illegal_syscall
49
50	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
51	bgez	t3, stackargs
52
53stack_done:
54	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
55	li	t1, _TIF_WORK_SYSCALL_ENTRY
56	and	t0, t1
57	bnez	t0, syscall_trace_entry # -> yes
58
59	jalr	t2			# Do The Real Thing (TM)
60
61	li	t0, -EMAXERRNO - 1	# error?
62	sltu	t0, t0, v0
63	sw	t0, PT_R7(sp)		# set error flag
64	beqz	t0, 1f
65
66	lw	t1, PT_R2(sp)		# syscall number
67	negu	v0			# error
68	sw	t1, PT_R0(sp)		# save it for syscall restarting
691:	sw	v0, PT_R2(sp)		# result
70
71o32_syscall_exit:
72	j	syscall_exit_partial
73
74/* ------------------------------------------------------------------------ */
75
76syscall_trace_entry:
77	SAVE_STATIC
78	move	s0, t2
79	move	a0, sp
80	jal	syscall_trace_enter
81
82	move	t0, s0
83	RESTORE_STATIC
84	lw	a0, PT_R4(sp)		# Restore argument registers
85	lw	a1, PT_R5(sp)
86	lw	a2, PT_R6(sp)
87	lw	a3, PT_R7(sp)
88	jalr	t0
89
90	li	t0, -EMAXERRNO - 1	# error?
91	sltu	t0, t0, v0
92	sw	t0, PT_R7(sp)		# set error flag
93	beqz	t0, 1f
94
95	lw	t1, PT_R2(sp)		# syscall number
96	negu	v0			# error
97	sw	t1, PT_R0(sp)		# save it for syscall restarting
981:	sw	v0, PT_R2(sp)		# result
99
100	j	syscall_exit
101
102/* ------------------------------------------------------------------------ */
103
104	/*
105	 * More than four arguments.  Try to deal with it by copying the
106	 * stack arguments from the user stack to the kernel stack.
107	 * This Sucks (TM).
108	 */
109stackargs:
110	lw	t0, PT_R29(sp)		# get old user stack pointer
111
112	/*
113	 * We intentionally keep the kernel stack a little below the top of
114	 * userspace so we don't have to do a slower byte accurate check here.
115	 */
116	lw	t5, TI_ADDR_LIMIT($28)
117	addu	t4, t0, 32
118	and	t5, t4
119	bltz	t5, bad_stack		# -> sp is bad
120
121	/* Ok, copy the args from the luser stack to the kernel stack.
122	 * t3 is the precomputed number of instruction bytes needed to
123	 * load or store arguments 6-8.
124	 */
125
126	la	t1, 5f			# load up to 3 arguments
127	subu	t1, t3
1281:	lw	t5, 16(t0)		# argument #5 from usp
129	.set	push
130	.set	noreorder
131	.set	nomacro
132	jr	t1
133	 addiu	t1, 6f - 5f
134
1352:	lw	t8, 28(t0)		# argument #8 from usp
1363:	lw	t7, 24(t0)		# argument #7 from usp
1374:	lw	t6, 20(t0)		# argument #6 from usp
1385:	jr	t1
139	 sw	t5, 16(sp)		# argument #5 to ksp
140
141#ifdef CONFIG_CPU_MICROMIPS
142	sw	t8, 28(sp)		# argument #8 to ksp
143	nop
144	sw	t7, 24(sp)		# argument #7 to ksp
145	nop
146	sw	t6, 20(sp)		# argument #6 to ksp
147	nop
148#else
149	sw	t8, 28(sp)		# argument #8 to ksp
150	sw	t7, 24(sp)		# argument #7 to ksp
151	sw	t6, 20(sp)		# argument #6 to ksp
152#endif
1536:	j	stack_done		# go back
154	 nop
155	.set	pop
156
157	.section __ex_table,"a"
158	PTR	1b,bad_stack
159	PTR	2b,bad_stack
160	PTR	3b,bad_stack
161	PTR	4b,bad_stack
162	.previous
163
164	/*
165	 * The stackpointer for a call with more than 4 arguments is bad.
166	 * We probably should handle this case a bit more drastic.
167	 */
168bad_stack:
169	li	v0, EFAULT
170	sw	v0, PT_R2(sp)
171	li	t0, 1				# set error flag
172	sw	t0, PT_R7(sp)
173	j	o32_syscall_exit
174
175	/*
176	 * The system call does not exist in this kernel
177	 */
178illegal_syscall:
179	li	v0, ENOSYS			# error
180	sw	v0, PT_R2(sp)
181	li	t0, 1				# set error flag
182	sw	t0, PT_R7(sp)
183	j	o32_syscall_exit
184	END(handle_sys)
185
186	LEAF(sys_syscall)
187	subu	t0, a0, __NR_O32_Linux	# check syscall number
188	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
189	beqz	t0, einval		# do not recurse
190	sll	t1, t0, 3
191	beqz	v0, einval
192	lw	t2, sys_call_table(t1)		# syscall routine
193
194	/* Some syscalls like execve get their arguments from struct pt_regs
195	   and claim zero arguments in the syscall table. Thus we have to
196	   assume the worst case and shuffle around all potential arguments.
197	   If you want performance, don't use indirect syscalls. */
198
199	move	a0, a1				# shift argument registers
200	move	a1, a2
201	move	a2, a3
202	lw	a3, 16(sp)
203	lw	t4, 20(sp)
204	lw	t5, 24(sp)
205	lw	t6, 28(sp)
206	sw	t4, 16(sp)
207	sw	t5, 20(sp)
208	sw	t6, 24(sp)
209	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some
210	sw	a1, PT_R5(sp)			# syscalls expect them there
211	sw	a2, PT_R6(sp)
212	sw	a3, PT_R7(sp)
213	sw	a3, PT_R26(sp)			# update a3 for syscall restarting
214	jr	t2
215	/* Unreached */
216
217einval: li	v0, -ENOSYS
218	jr	ra
219	END(sys_syscall)
220
221	.macro	fifty ptr, nargs, from=1, to=50
222	sys	\ptr		\nargs
223	.if	\to-\from
224	fifty	\ptr,\nargs,"(\from+1)",\to
225	.endif
226	.endm
227
228	.macro	mille ptr, nargs, from=1, to=20
229	fifty	\ptr,\nargs
230	.if	\to-\from
231	mille	\ptr,\nargs,"(\from+1)",\to
232	.endif
233	.endm
234
235	.macro	syscalltable
236	sys	sys_syscall		8	/* 4000 */
237	sys	sys_exit		1
238	sys	__sys_fork		0
239	sys	sys_read		3
240	sys	sys_write		3
241	sys	sys_open		3	/* 4005 */
242	sys	sys_close		1
243	sys	sys_waitpid		3
244	sys	sys_creat		2
245	sys	sys_link		2
246	sys	sys_unlink		1	/* 4010 */
247	sys	sys_execve		0
248	sys	sys_chdir		1
249	sys	sys_time		1
250	sys	sys_mknod		3
251	sys	sys_chmod		2	/* 4015 */
252	sys	sys_lchown		3
253	sys	sys_ni_syscall		0
254	sys	sys_ni_syscall		0	/* was sys_stat */
255	sys	sys_lseek		3
256	sys	sys_getpid		0	/* 4020 */
257	sys	sys_mount		5
258	sys	sys_oldumount		1
259	sys	sys_setuid		1
260	sys	sys_getuid		0
261	sys	sys_stime		1	/* 4025 */
262	sys	sys_ptrace		4
263	sys	sys_alarm		1
264	sys	sys_ni_syscall		0	/* was sys_fstat */
265	sys	sys_pause		0
266	sys	sys_utime		2	/* 4030 */
267	sys	sys_ni_syscall		0
268	sys	sys_ni_syscall		0
269	sys	sys_access		2
270	sys	sys_nice		1
271	sys	sys_ni_syscall		0	/* 4035 */
272	sys	sys_sync		0
273	sys	sys_kill		2
274	sys	sys_rename		2
275	sys	sys_mkdir		2
276	sys	sys_rmdir		1	/* 4040 */
277	sys	sys_dup			1
278	sys	sysm_pipe		0
279	sys	sys_times		1
280	sys	sys_ni_syscall		0
281	sys	sys_brk			1	/* 4045 */
282	sys	sys_setgid		1
283	sys	sys_getgid		0
284	sys	sys_ni_syscall		0	/* was signal(2) */
285	sys	sys_geteuid		0
286	sys	sys_getegid		0	/* 4050 */
287	sys	sys_acct		1
288	sys	sys_umount		2
289	sys	sys_ni_syscall		0
290	sys	sys_ioctl		3
291	sys	sys_fcntl		3	/* 4055 */
292	sys	sys_ni_syscall		2
293	sys	sys_setpgid		2
294	sys	sys_ni_syscall		0
295	sys	sys_olduname		1
296	sys	sys_umask		1	/* 4060 */
297	sys	sys_chroot		1
298	sys	sys_ustat		2
299	sys	sys_dup2		2
300	sys	sys_getppid		0
301	sys	sys_getpgrp		0	/* 4065 */
302	sys	sys_setsid		0
303	sys	sys_sigaction		3
304	sys	sys_sgetmask		0
305	sys	sys_ssetmask		1
306	sys	sys_setreuid		2	/* 4070 */
307	sys	sys_setregid		2
308	sys	sys_sigsuspend		0
309	sys	sys_sigpending		1
310	sys	sys_sethostname		2
311	sys	sys_setrlimit		2	/* 4075 */
312	sys	sys_getrlimit		2
313	sys	sys_getrusage		2
314	sys	sys_gettimeofday	2
315	sys	sys_settimeofday	2
316	sys	sys_getgroups		2	/* 4080 */
317	sys	sys_setgroups		2
318	sys	sys_ni_syscall		0	/* old_select */
319	sys	sys_symlink		2
320	sys	sys_ni_syscall		0	/* was sys_lstat */
321	sys	sys_readlink		3	/* 4085 */
322	sys	sys_uselib		1
323	sys	sys_swapon		2
324	sys	sys_reboot		3
325	sys	sys_old_readdir		3
326	sys	sys_mips_mmap		6	/* 4090 */
327	sys	sys_munmap		2
328	sys	sys_truncate		2
329	sys	sys_ftruncate		2
330	sys	sys_fchmod		2
331	sys	sys_fchown		3	/* 4095 */
332	sys	sys_getpriority		2
333	sys	sys_setpriority		3
334	sys	sys_ni_syscall		0
335	sys	sys_statfs		2
336	sys	sys_fstatfs		2	/* 4100 */
337	sys	sys_ni_syscall		0	/* was ioperm(2) */
338	sys	sys_socketcall		2
339	sys	sys_syslog		3
340	sys	sys_setitimer		3
341	sys	sys_getitimer		2	/* 4105 */
342	sys	sys_newstat		2
343	sys	sys_newlstat		2
344	sys	sys_newfstat		2
345	sys	sys_uname		1
346	sys	sys_ni_syscall		0	/* 4110 was iopl(2) */
347	sys	sys_vhangup		0
348	sys	sys_ni_syscall		0	/* was sys_idle() */
349	sys	sys_ni_syscall		0	/* was sys_vm86 */
350	sys	sys_wait4		4
351	sys	sys_swapoff		1	/* 4115 */
352	sys	sys_sysinfo		1
353	sys	sys_ipc			6
354	sys	sys_fsync		1
355	sys	sys_sigreturn		0
356	sys	__sys_clone		6	/* 4120 */
357	sys	sys_setdomainname	2
358	sys	sys_newuname		1
359	sys	sys_ni_syscall		0	/* sys_modify_ldt */
360	sys	sys_adjtimex		1
361	sys	sys_mprotect		3	/* 4125 */
362	sys	sys_sigprocmask		3
363	sys	sys_ni_syscall		0	/* was create_module */
364	sys	sys_init_module		5
365	sys	sys_delete_module	1
366	sys	sys_ni_syscall		0	/* 4130 was get_kernel_syms */
367	sys	sys_quotactl		4
368	sys	sys_getpgid		1
369	sys	sys_fchdir		1
370	sys	sys_bdflush		2
371	sys	sys_sysfs		3	/* 4135 */
372	sys	sys_personality		1
373	sys	sys_ni_syscall		0	/* for afs_syscall */
374	sys	sys_setfsuid		1
375	sys	sys_setfsgid		1
376	sys	sys_llseek		5	/* 4140 */
377	sys	sys_getdents		3
378	sys	sys_select		5
379	sys	sys_flock		2
380	sys	sys_msync		3
381	sys	sys_readv		3	/* 4145 */
382	sys	sys_writev		3
383	sys	sys_cacheflush		3
384	sys	sys_cachectl		3
385	sys	sys_sysmips		4
386	sys	sys_ni_syscall		0	/* 4150 */
387	sys	sys_getsid		1
388	sys	sys_fdatasync		1
389	sys	sys_sysctl		1
390	sys	sys_mlock		2
391	sys	sys_munlock		2	/* 4155 */
392	sys	sys_mlockall		1
393	sys	sys_munlockall		0
394	sys	sys_sched_setparam	2
395	sys	sys_sched_getparam	2
396	sys	sys_sched_setscheduler	3	/* 4160 */
397	sys	sys_sched_getscheduler	1
398	sys	sys_sched_yield		0
399	sys	sys_sched_get_priority_max 1
400	sys	sys_sched_get_priority_min 1
401	sys	sys_sched_rr_get_interval 2	/* 4165 */
402	sys	sys_nanosleep,		2
403	sys	sys_mremap,		5
404	sys	sys_accept		3
405	sys	sys_bind		3
406	sys	sys_connect		3	/* 4170 */
407	sys	sys_getpeername		3
408	sys	sys_getsockname		3
409	sys	sys_getsockopt		5
410	sys	sys_listen		2
411	sys	sys_recv		4	/* 4175 */
412	sys	sys_recvfrom		6
413	sys	sys_recvmsg		3
414	sys	sys_send		4
415	sys	sys_sendmsg		3
416	sys	sys_sendto		6	/* 4180 */
417	sys	sys_setsockopt		5
418	sys	sys_shutdown		2
419	sys	sys_socket		3
420	sys	sys_socketpair		4
421	sys	sys_setresuid		3	/* 4185 */
422	sys	sys_getresuid		3
423	sys	sys_ni_syscall		0	/* was sys_query_module */
424	sys	sys_poll		3
425	sys	sys_ni_syscall		0	/* was nfsservctl */
426	sys	sys_setresgid		3	/* 4190 */
427	sys	sys_getresgid		3
428	sys	sys_prctl		5
429	sys	sys_rt_sigreturn	0
430	sys	sys_rt_sigaction	4
431	sys	sys_rt_sigprocmask	4	/* 4195 */
432	sys	sys_rt_sigpending	2
433	sys	sys_rt_sigtimedwait	4
434	sys	sys_rt_sigqueueinfo	3
435	sys	sys_rt_sigsuspend	0
436	sys	sys_pread64		6	/* 4200 */
437	sys	sys_pwrite64		6
438	sys	sys_chown		3
439	sys	sys_getcwd		2
440	sys	sys_capget		2
441	sys	sys_capset		2	/* 4205 */
442	sys	sys_sigaltstack		0
443	sys	sys_sendfile		4
444	sys	sys_ni_syscall		0
445	sys	sys_ni_syscall		0
446	sys	sys_mips_mmap2		6	/* 4210 */
447	sys	sys_truncate64		4
448	sys	sys_ftruncate64		4
449	sys	sys_stat64		2
450	sys	sys_lstat64		2
451	sys	sys_fstat64		2	/* 4215 */
452	sys	sys_pivot_root		2
453	sys	sys_mincore		3
454	sys	sys_madvise		3
455	sys	sys_getdents64		3
456	sys	sys_fcntl64		3	/* 4220 */
457	sys	sys_ni_syscall		0
458	sys	sys_gettid		0
459	sys	sys_readahead		5
460	sys	sys_setxattr		5
461	sys	sys_lsetxattr		5	/* 4225 */
462	sys	sys_fsetxattr		5
463	sys	sys_getxattr		4
464	sys	sys_lgetxattr		4
465	sys	sys_fgetxattr		4
466	sys	sys_listxattr		3	/* 4230 */
467	sys	sys_llistxattr		3
468	sys	sys_flistxattr		3
469	sys	sys_removexattr		2
470	sys	sys_lremovexattr	2
471	sys	sys_fremovexattr	2	/* 4235 */
472	sys	sys_tkill		2
473	sys	sys_sendfile64		5
474	sys	sys_futex		6
475#ifdef CONFIG_MIPS_MT_FPAFF
476	/*
477	 * For FPU affinity scheduling on MIPS MT processors, we need to
478	 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
479	 * in kernel/sched/core.c.  Considered only temporary we only support
480	 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
481	 * atm.
482	 */
483	sys	mipsmt_sys_sched_setaffinity	3
484	sys	mipsmt_sys_sched_getaffinity	3
485#else
486	sys	sys_sched_setaffinity	3
487	sys	sys_sched_getaffinity	3	/* 4240 */
488#endif /* CONFIG_MIPS_MT_FPAFF */
489	sys	sys_io_setup		2
490	sys	sys_io_destroy		1
491	sys	sys_io_getevents	5
492	sys	sys_io_submit		3
493	sys	sys_io_cancel		3	/* 4245 */
494	sys	sys_exit_group		1
495	sys	sys_lookup_dcookie	4
496	sys	sys_epoll_create	1
497	sys	sys_epoll_ctl		4
498	sys	sys_epoll_wait		4	/* 4250 */
499	sys	sys_remap_file_pages	5
500	sys	sys_set_tid_address	1
501	sys	sys_restart_syscall	0
502	sys	sys_fadvise64_64	7
503	sys	sys_statfs64		3	/* 4255 */
504	sys	sys_fstatfs64		2
505	sys	sys_timer_create	3
506	sys	sys_timer_settime	4
507	sys	sys_timer_gettime	2
508	sys	sys_timer_getoverrun	1	/* 4260 */
509	sys	sys_timer_delete	1
510	sys	sys_clock_settime	2
511	sys	sys_clock_gettime	2
512	sys	sys_clock_getres	2
513	sys	sys_clock_nanosleep	4	/* 4265 */
514	sys	sys_tgkill		3
515	sys	sys_utimes		2
516	sys	sys_mbind		4
517	sys	sys_ni_syscall		0	/* sys_get_mempolicy */
518	sys	sys_ni_syscall		0	/* 4270 sys_set_mempolicy */
519	sys	sys_mq_open		4
520	sys	sys_mq_unlink		1
521	sys	sys_mq_timedsend	5
522	sys	sys_mq_timedreceive	5
523	sys	sys_mq_notify		2	/* 4275 */
524	sys	sys_mq_getsetattr	3
525	sys	sys_ni_syscall		0	/* sys_vserver */
526	sys	sys_waitid		5
527	sys	sys_ni_syscall		0	/* available, was setaltroot */
528	sys	sys_add_key		5	/* 4280 */
529	sys	sys_request_key		4
530	sys	sys_keyctl		5
531	sys	sys_set_thread_area	1
532	sys	sys_inotify_init	0
533	sys	sys_inotify_add_watch	3	/* 4285 */
534	sys	sys_inotify_rm_watch	2
535	sys	sys_migrate_pages	4
536	sys	sys_openat		4
537	sys	sys_mkdirat		3
538	sys	sys_mknodat		4	/* 4290 */
539	sys	sys_fchownat		5
540	sys	sys_futimesat		3
541	sys	sys_fstatat64		4
542	sys	sys_unlinkat		3
543	sys	sys_renameat		4	/* 4295 */
544	sys	sys_linkat		5
545	sys	sys_symlinkat		3
546	sys	sys_readlinkat		4
547	sys	sys_fchmodat		3
548	sys	sys_faccessat		3	/* 4300 */
549	sys	sys_pselect6		6
550	sys	sys_ppoll		5
551	sys	sys_unshare		1
552	sys	sys_splice		6
553	sys	sys_sync_file_range	7	/* 4305 */
554	sys	sys_tee			4
555	sys	sys_vmsplice		4
556	sys	sys_move_pages		6
557	sys	sys_set_robust_list	2
558	sys	sys_get_robust_list	3	/* 4310 */
559	sys	sys_kexec_load		4
560	sys	sys_getcpu		3
561	sys	sys_epoll_pwait		6
562	sys	sys_ioprio_set		3
563	sys	sys_ioprio_get		2	/* 4315 */
564	sys	sys_utimensat		4
565	sys	sys_signalfd		3
566	sys	sys_ni_syscall		0	/* was timerfd */
567	sys	sys_eventfd		1
568	sys	sys_fallocate		6	/* 4320 */
569	sys	sys_timerfd_create	2
570	sys	sys_timerfd_gettime	2
571	sys	sys_timerfd_settime	4
572	sys	sys_signalfd4		4
573	sys	sys_eventfd2		2	/* 4325 */
574	sys	sys_epoll_create1	1
575	sys	sys_dup3		3
576	sys	sys_pipe2		2
577	sys	sys_inotify_init1	1
578	sys	sys_preadv		6	/* 4330 */
579	sys	sys_pwritev		6
580	sys	sys_rt_tgsigqueueinfo	4
581	sys	sys_perf_event_open	5
582	sys	sys_accept4		4
583	sys	sys_recvmmsg		5	/* 4335 */
584	sys	sys_fanotify_init	2
585	sys	sys_fanotify_mark	6
586	sys	sys_prlimit64		4
587	sys	sys_name_to_handle_at	5
588	sys	sys_open_by_handle_at	3	/* 4340 */
589	sys	sys_clock_adjtime	2
590	sys	sys_syncfs		1
591	sys	sys_sendmmsg		4
592	sys	sys_setns		2
593	sys	sys_process_vm_readv	6	/* 4345 */
594	sys	sys_process_vm_writev	6
595	sys	sys_kcmp		5
596	sys	sys_finit_module	3
597	.endm
598
599	/* We pre-compute the number of _instruction_ bytes needed to
600	   load or store the arguments 6-8. Negative values are ignored. */
601
602	.macro	sys function, nargs
603	PTR	\function
604	LONG	(\nargs << 2) - (5 << 2)
605	.endm
606
607	.align	3
608	.type	sys_call_table,@object
609EXPORT(sys_call_table)
610	syscalltable
611	.size	sys_call_table, . - sys_call_table
612