xref: /linux/arch/mips/kernel/scall64-o32.S (revision 4854c7b27f0975a2b629f35ea3996d2968eb7c4f)
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 - 2000, 2001 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2001 MIPS Technologies, Inc.
9 * Copyright (C) 2004 Thiemo Seufer
10 *
11 * Hairy, the userspace application uses a different argument passing
12 * convention than the kernel, so we have to translate things from o32
13 * to ABI64 calling convention.  64-bit syscalls are also processed
14 * here for now.
15 */
16#include <linux/config.h>
17#include <linux/errno.h>
18#include <asm/asm.h>
19#include <asm/asmmacro.h>
20#include <asm/mipsregs.h>
21#include <asm/regdef.h>
22#include <asm/stackframe.h>
23#include <asm/thread_info.h>
24#include <asm/unistd.h>
25#include <asm/sysmips.h>
26
27	.align  5
28NESTED(handle_sys, PT_SIZE, sp)
29	.set	noat
30	SAVE_SOME
31	STI
32	.set	at
33	ld	t1, PT_EPC(sp)		# skip syscall on return
34
35	dsubu	t0, v0, __NR_O32_Linux	# check syscall number
36	sltiu	t0, t0, __NR_O32_Linux_syscalls + 1
37	daddiu	t1, 4			# skip to next instruction
38	sd	t1, PT_EPC(sp)
39	beqz	t0, not_o32_scall
40#if 0
41 SAVE_ALL
42 move a1, v0
43 PRINT("Scall %ld\n")
44 RESTORE_ALL
45#endif
46
47	/* We don't want to stumble over broken sign extensions from
48	   userland. O32 does never use the upper half. */
49	sll	a0, a0, 0
50	sll	a1, a1, 0
51	sll	a2, a2, 0
52	sll	a3, a3, 0
53
54	dsll	t0, v0, 3		# offset into table
55	ld	t2, (sys_call_table - (__NR_O32_Linux * 8))(t0)
56
57	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
58
59	/*
60	 * More than four arguments.  Try to deal with it by copying the
61	 * stack arguments from the user stack to the kernel stack.
62	 * This Sucks (TM).
63	 *
64	 * We intentionally keep the kernel stack a little below the top of
65	 * userspace so we don't have to do a slower byte accurate check here.
66	 */
67	ld	t0, PT_R29(sp)		# get old user stack pointer
68	daddu	t1, t0, 32
69	bltz	t1, bad_stack
70
711:	lw	a4, 16(t0)		# argument #5 from usp
722:	lw	a5, 20(t0)		# argument #6 from usp
733:	lw	a6, 24(t0)		# argument #7 from usp
744:	lw	a7, 28(t0)		# argument #8 from usp (for indirect syscalls)
75
76	.section __ex_table,"a"
77	PTR	1b, bad_stack
78	PTR	2b, bad_stack
79	PTR	3b, bad_stack
80	PTR	4b, bad_stack
81	.previous
82
83	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
84	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
85	and	t0, t1, t0
86	bnez	t0, trace_a_syscall
87
88	jalr	t2			# Do The Real Thing (TM)
89
90	li	t0, -EMAXERRNO - 1	# error?
91	sltu	t0, t0, v0
92	sd	t0, PT_R7(sp)		# set error flag
93	beqz	t0, 1f
94
95	dnegu	v0			# error
96	sd	v0, PT_R0(sp)		# flag for syscall restarting
971:	sd	v0, PT_R2(sp)		# result
98
99o32_syscall_exit:
100	local_irq_disable		# make need_resched and
101					# signals dont change between
102					# sampling and return
103	LONG_L	a2, TI_FLAGS($28)
104	li	t0, _TIF_ALLWORK_MASK
105	and	t0, a2, t0
106	bnez	t0, o32_syscall_exit_work
107
108	j	restore_partial
109
110o32_syscall_exit_work:
111	j	syscall_exit_work_partial
112
113/* ------------------------------------------------------------------------ */
114
115trace_a_syscall:
116	SAVE_STATIC
117	sd	a4, PT_R8(sp)		# Save argument registers
118	sd	a5, PT_R9(sp)
119	sd	a6, PT_R10(sp)
120	sd	a7, PT_R11(sp)		# For indirect syscalls
121
122	move	s0, t2			# Save syscall pointer
123	move	a0, sp
124	li	a1, 0
125	jal	do_syscall_trace
126
127	move	t0, s0
128	RESTORE_STATIC
129	ld	a0, PT_R4(sp)		# Restore argument registers
130	ld	a1, PT_R5(sp)
131	ld	a2, PT_R6(sp)
132	ld	a3, PT_R7(sp)
133	ld	a4, PT_R8(sp)
134	ld	a5, PT_R9(sp)
135	ld	a6, PT_R10(sp)
136	ld	a7, PT_R11(sp)		# For indirect syscalls
137	jalr	t0
138
139	li	t0, -EMAXERRNO - 1	# error?
140	sltu	t0, t0, v0
141	sd	t0, PT_R7(sp)		# set error flag
142	beqz	t0, 1f
143
144	dnegu	v0			# error
145	sd	v0, PT_R0(sp)		# set flag for syscall restarting
1461:	sd	v0, PT_R2(sp)		# result
147
148	j	syscall_exit
149
150/* ------------------------------------------------------------------------ */
151
152	/*
153	 * The stackpointer for a call with more than 4 arguments is bad.
154	 */
155bad_stack:
156	dnegu	v0			# error
157	sd	v0, PT_R0(sp)
158	sd	v0, PT_R2(sp)
159	li	t0, 1			# set error flag
160	sd	t0, PT_R7(sp)
161	j	o32_syscall_exit
162
163not_o32_scall:
164	/*
165	 * This is not an o32 compatibility syscall, pass it on
166	 * to the 64-bit syscall handlers.
167	 */
168#ifdef CONFIG_MIPS32_N32
169	j	handle_sysn32
170#else
171	j	handle_sys64
172#endif
173	END(handle_sys)
174
175LEAF(sys32_syscall)
176	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
177	beqz	v0, einval
178
179	dsll	v0, a0, 3
180	ld	t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
181
182	li	v1, 4000		# indirect syscall number
183	beq	a0, v1, einval		# do not recurse
184
185	move	a0, a1			# shift argument registers
186	move	a1, a2
187	move	a2, a3
188	move	a3, a4
189	move	a4, a5
190	move	a5, a6
191	move	a6, a7
192	sd	a0, PT_R4(sp)		# ... and push back a0 - a3, some
193	sd	a1, PT_R5(sp)		# syscalls expect them there
194	sd	a2, PT_R6(sp)
195	sd	a3, PT_R7(sp)
196	sd	a3, PT_R26(sp)		# update a3 for syscall restarting
197	jr	t2
198	/* Unreached */
199
200einval:	li	v0, -EINVAL
201	jr	ra
202	END(sys32_syscall)
203
204	.align	3
205	.type	sys_call_table,@object
206sys_call_table:
207	PTR	sys32_syscall			/* 4000 */
208	PTR	sys_exit
209	PTR	sys_fork
210	PTR	sys_read
211	PTR	sys_write
212	PTR	compat_sys_open			/* 4005 */
213	PTR	sys_close
214	PTR	sys_waitpid
215	PTR	sys_creat
216	PTR	sys_link
217	PTR	sys_unlink			/* 4010 */
218	PTR	sys32_execve
219	PTR	sys_chdir
220	PTR	compat_sys_time
221	PTR	sys_mknod
222	PTR	sys_chmod			/* 4015 */
223	PTR	sys_lchown
224	PTR	sys_ni_syscall
225	PTR	sys_ni_syscall			/* was sys_stat */
226	PTR	sys_lseek
227	PTR	sys_getpid			/* 4020 */
228	PTR	sys_mount
229	PTR	sys_oldumount
230	PTR	sys_setuid
231	PTR	sys_getuid
232	PTR	compat_sys_stime		/* 4025 */
233	PTR	sys32_ptrace
234	PTR	sys_alarm
235	PTR	sys_ni_syscall			/* was sys_fstat */
236	PTR	sys_pause
237	PTR	compat_sys_utime		/* 4030 */
238	PTR	sys_ni_syscall
239	PTR	sys_ni_syscall
240	PTR	sys_access
241	PTR	sys_nice
242	PTR	sys_ni_syscall			/* 4035 */
243	PTR	sys_sync
244	PTR	sys_kill
245	PTR	sys_rename
246	PTR	sys_mkdir
247	PTR	sys_rmdir			/* 4040 */
248	PTR	sys_dup
249	PTR	sys_pipe
250	PTR	compat_sys_times
251	PTR	sys_ni_syscall
252	PTR	sys_brk				/* 4045 */
253	PTR	sys_setgid
254	PTR	sys_getgid
255	PTR	sys_ni_syscall			/* was signal	2 */
256	PTR	sys_geteuid
257	PTR	sys_getegid			/* 4050 */
258	PTR	sys_acct
259	PTR	sys_umount
260	PTR	sys_ni_syscall
261	PTR	compat_sys_ioctl
262	PTR	compat_sys_fcntl		/* 4055 */
263	PTR	sys_ni_syscall
264	PTR	sys_setpgid
265	PTR	sys_ni_syscall
266	PTR	sys_olduname
267	PTR	sys_umask			/* 4060 */
268	PTR	sys_chroot
269	PTR	sys32_ustat
270	PTR	sys_dup2
271	PTR	sys_getppid
272	PTR	sys_getpgrp			/* 4065 */
273	PTR	sys_setsid
274	PTR	sys32_sigaction
275	PTR	sys_sgetmask
276	PTR	sys_ssetmask
277	PTR	sys_setreuid			/* 4070 */
278	PTR	sys_setregid
279	PTR	sys32_sigsuspend
280	PTR	compat_sys_sigpending
281	PTR	sys_sethostname
282	PTR	compat_sys_setrlimit		/* 4075 */
283	PTR	compat_sys_getrlimit
284	PTR	compat_sys_getrusage
285	PTR	sys32_gettimeofday
286	PTR	sys32_settimeofday
287	PTR	sys_getgroups			/* 4080 */
288	PTR	sys_setgroups
289	PTR	sys_ni_syscall			/* old_select */
290	PTR	sys_symlink
291	PTR	sys_ni_syscall			/* was sys_lstat */
292	PTR	sys_readlink			/* 4085 */
293	PTR	sys_uselib
294	PTR	sys_swapon
295	PTR	sys_reboot
296	PTR	compat_sys_old_readdir
297	PTR	old_mmap			/* 4090 */
298	PTR	sys_munmap
299	PTR	sys_truncate
300	PTR	sys_ftruncate
301	PTR	sys_fchmod
302	PTR	sys_fchown			/* 4095 */
303	PTR	sys_getpriority
304	PTR	sys_setpriority
305	PTR	sys_ni_syscall
306	PTR	compat_sys_statfs
307	PTR	compat_sys_fstatfs		/* 4100 */
308	PTR	sys_ni_syscall			/* sys_ioperm */
309	PTR	sys32_socketcall
310	PTR	sys_syslog
311	PTR	compat_sys_setitimer
312	PTR	compat_sys_getitimer		/* 4105 */
313	PTR	compat_sys_newstat
314	PTR	compat_sys_newlstat
315	PTR	compat_sys_newfstat
316	PTR	sys_uname
317	PTR	sys_ni_syscall			/* sys_ioperm  *//* 4110 */
318	PTR	sys_vhangup
319	PTR	sys_ni_syscall			/* was sys_idle	 */
320	PTR	sys_ni_syscall			/* sys_vm86 */
321	PTR	compat_sys_wait4
322	PTR	sys_swapoff			/* 4115 */
323	PTR	sys32_sysinfo
324	PTR	sys32_ipc
325	PTR	sys_fsync
326	PTR	sys32_sigreturn
327	PTR	sys32_clone			/* 4120 */
328	PTR	sys_setdomainname
329	PTR	sys32_newuname
330	PTR	sys_ni_syscall			/* sys_modify_ldt */
331	PTR	compat_sys_adjtimex
332	PTR	sys_mprotect			/* 4125 */
333	PTR	compat_sys_sigprocmask
334	PTR	sys_ni_syscall			/* was creat_module */
335	PTR	sys_init_module
336	PTR	sys_delete_module
337	PTR	sys_ni_syscall			/* 4130, get_kernel_syms */
338	PTR	sys_quotactl
339	PTR	sys_getpgid
340	PTR	sys_fchdir
341	PTR	sys_bdflush
342	PTR	sys_sysfs			/* 4135 */
343	PTR	sys32_personality
344	PTR	sys_ni_syscall	 		/* for afs_syscall */
345	PTR	sys_setfsuid
346	PTR	sys_setfsgid
347	PTR	sys32_llseek			/* 4140 */
348	PTR	compat_sys_getdents
349	PTR	compat_sys_select
350	PTR	sys_flock
351	PTR	sys_msync
352	PTR	compat_sys_readv		/* 4145 */
353	PTR	compat_sys_writev
354	PTR	sys_cacheflush
355	PTR	sys_cachectl
356	PTR	sys_sysmips
357	PTR	sys_ni_syscall			/* 4150 */
358	PTR	sys_getsid
359	PTR	sys_fdatasync
360	PTR	sys32_sysctl
361	PTR	sys_mlock
362	PTR	sys_munlock			/* 4155 */
363	PTR	sys_mlockall
364	PTR	sys_munlockall
365	PTR	sys_sched_setparam
366	PTR	sys_sched_getparam
367	PTR	sys_sched_setscheduler 		/* 4160 */
368	PTR	sys_sched_getscheduler
369	PTR	sys_sched_yield
370	PTR	sys_sched_get_priority_max
371	PTR	sys_sched_get_priority_min
372	PTR	sys32_sched_rr_get_interval 	/* 4165 */
373	PTR	compat_sys_nanosleep
374	PTR	sys_mremap
375	PTR	sys_accept
376	PTR	sys_bind
377	PTR	sys_connect			/* 4170 */
378	PTR	sys_getpeername
379	PTR	sys_getsockname
380	PTR	sys_getsockopt
381	PTR	sys_listen
382	PTR	sys_recv			/* 4175 */
383	PTR	sys_recvfrom
384	PTR	compat_sys_recvmsg
385	PTR	sys_send
386	PTR	compat_sys_sendmsg
387	PTR	sys_sendto			/* 4180 */
388	PTR	compat_sys_setsockopt
389	PTR	sys_shutdown
390	PTR	sys_socket
391	PTR	sys_socketpair
392	PTR	sys_setresuid			/* 4185 */
393	PTR	sys_getresuid
394	PTR	sys_ni_syscall			/* was query_module */
395	PTR	sys_poll
396	PTR	compat_sys_nfsservctl
397	PTR	sys_setresgid			/* 4190 */
398	PTR	sys_getresgid
399	PTR	sys_prctl
400	PTR	sys32_rt_sigreturn
401	PTR	sys32_rt_sigaction
402	PTR	sys32_rt_sigprocmask 		/* 4195 */
403	PTR	sys32_rt_sigpending
404	PTR	compat_sys_rt_sigtimedwait
405	PTR	sys32_rt_sigqueueinfo
406	PTR	sys32_rt_sigsuspend
407	PTR	sys32_pread			/* 4200 */
408	PTR	sys32_pwrite
409	PTR	sys_chown
410	PTR	sys_getcwd
411	PTR	sys_capget
412	PTR	sys_capset			/* 4205 */
413	PTR	sys32_sigaltstack
414	PTR	sys32_sendfile
415	PTR	sys_ni_syscall
416	PTR	sys_ni_syscall
417	PTR	sys32_mmap2			/* 4210 */
418	PTR	sys32_truncate64
419	PTR	sys32_ftruncate64
420	PTR	sys_newstat
421	PTR	sys_newlstat
422	PTR	sys_newfstat			/* 4215 */
423	PTR	sys_pivot_root
424	PTR	sys_mincore
425	PTR	sys_madvise
426	PTR	sys_getdents64
427	PTR	compat_sys_fcntl64		/* 4220 */
428	PTR	sys_ni_syscall
429	PTR	sys_gettid
430	PTR	sys32_readahead
431	PTR	sys_setxattr
432	PTR	sys_lsetxattr			/* 4225 */
433	PTR	sys_fsetxattr
434	PTR	sys_getxattr
435	PTR	sys_lgetxattr
436	PTR	sys_fgetxattr
437	PTR	sys_listxattr			/* 4230 */
438	PTR	sys_llistxattr
439	PTR	sys_flistxattr
440	PTR	sys_removexattr
441	PTR	sys_lremovexattr
442	PTR	sys_fremovexattr		/* 4235 */
443	PTR	sys_tkill
444	PTR	sys_sendfile64
445	PTR	compat_sys_futex
446	PTR	compat_sys_sched_setaffinity
447	PTR	compat_sys_sched_getaffinity	/* 4240 */
448	PTR	sys_io_setup
449	PTR	sys_io_destroy
450	PTR	sys_io_getevents
451	PTR	sys_io_submit
452	PTR	sys_io_cancel			/* 4245 */
453	PTR	sys_exit_group
454	PTR	sys_lookup_dcookie
455	PTR	sys_epoll_create
456	PTR	sys_epoll_ctl
457	PTR	sys_epoll_wait			/* 4250 */
458	PTR	sys_remap_file_pages
459	PTR	sys_set_tid_address
460	PTR	sys_restart_syscall
461	PTR	sys_fadvise64_64
462	PTR	compat_sys_statfs64		/* 4255 */
463	PTR	compat_sys_fstatfs64
464	PTR	sys32_timer_create
465	PTR	compat_sys_timer_settime
466	PTR	compat_sys_timer_gettime
467	PTR	sys_timer_getoverrun		/* 4260 */
468	PTR	sys_timer_delete
469	PTR	compat_sys_clock_settime
470	PTR	compat_sys_clock_gettime
471	PTR	compat_sys_clock_getres
472	PTR	compat_sys_clock_nanosleep	/* 4265 */
473	PTR	sys_tgkill
474	PTR	compat_sys_utimes
475	PTR	sys_ni_syscall			/* sys_mbind */
476	PTR	sys_ni_syscall			/* sys_get_mempolicy */
477	PTR	sys_ni_syscall			/* 4270 sys_set_mempolicy */
478	PTR	compat_sys_mq_open
479	PTR	sys_mq_unlink
480	PTR	compat_sys_mq_timedsend
481	PTR	compat_sys_mq_timedreceive
482	PTR	compat_sys_mq_notify		/* 4275 */
483	PTR	compat_sys_mq_getsetattr
484	PTR	sys_ni_syscall			/* sys_vserver */
485	PTR	sys32_waitid
486	PTR	sys_ni_syscall			/* available, was setaltroot */
487	PTR	sys_add_key			/* 4280 */
488	PTR	sys_request_key
489	PTR	sys_keyctl
490	PTR	sys_set_thread_area
491	PTR	sys_inotify_init
492	PTR	sys_inotify_add_watch		/* 4285 */
493	PTR	sys_inotify_rm_watch
494	PTR	sys_migrate_pages
495	PTR	compat_sys_openat
496	PTR	sys_mkdirat
497	PTR	sys_mknodat			/* 4290 */
498	PTR	sys_fchownat
499	PTR	compat_sys_futimesat
500	PTR	compat_sys_newfstatat
501	PTR	sys_unlinkat
502	PTR	sys_renameat			/* 4295 */
503	PTR	sys_linkat
504	PTR	sys_symlinkat
505	PTR	sys_readlinkat
506	PTR	sys_fchmodat
507	PTR	sys_faccessat			/* 4300 */
508	PTR	sys_pselect6
509	PTR	sys_ppoll
510	PTR	sys_unshare
511	PTR	sys_splice
512	PTR	sys32_sync_file_range		/* 4305 */
513	.size	sys_call_table,.-sys_call_table
514