xref: /openbmc/linux/arch/mips/kernel/scall64-o32.S (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
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	ld	a0, PT_R4(sp)		# Restore argument registers
128	ld	a1, PT_R5(sp)
129	ld	a2, PT_R6(sp)
130	ld	a3, PT_R7(sp)
131	ld	a4, PT_R8(sp)
132	ld	a5, PT_R9(sp)
133	ld	a6, PT_R10(sp)
134	ld	a7, PT_R11(sp)		# For indirect syscalls
135	jalr	s0
136
137	li	t0, -EMAXERRNO - 1	# error?
138	sltu	t0, t0, v0
139	sd	t0, PT_R7(sp)		# set error flag
140	beqz	t0, 1f
141
142	dnegu	v0			# error
143	sd	v0, PT_R0(sp)		# set flag for syscall restarting
1441:	sd	v0, PT_R2(sp)		# result
145
146	j	syscall_exit
147
148/* ------------------------------------------------------------------------ */
149
150	/*
151	 * The stackpointer for a call with more than 4 arguments is bad.
152	 */
153bad_stack:
154	dnegu	v0			# error
155	sd	v0, PT_R0(sp)
156	sd	v0, PT_R2(sp)
157	li	t0, 1			# set error flag
158	sd	t0, PT_R7(sp)
159	j	o32_syscall_exit
160
161not_o32_scall:
162	/*
163	 * This is not an o32 compatibility syscall, pass it on
164	 * to the 64-bit syscall handlers.
165	 */
166#ifdef CONFIG_MIPS32_N32
167	j	handle_sysn32
168#else
169	j	handle_sys64
170#endif
171	END(handle_sys)
172
173LEAF(sys32_syscall)
174	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
175	beqz	v0, einval
176
177	dsll	v0, a0, 3
178	ld	t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
179
180	li	v1, 4000		# indirect syscall number
181	beq	a0, v1, einval		# do not recurse
182
183	move	a0, a1			# shift argument registers
184	move	a1, a2
185	move	a2, a3
186	move	a3, a4
187	move	a4, a5
188	move	a5, a6
189	move	a6, a7
190	sd	a0, PT_R4(sp)		# ... and push back a0 - a3, some
191	sd	a1, PT_R5(sp)		# syscalls expect them there
192	sd	a2, PT_R6(sp)
193	sd	a3, PT_R7(sp)
194	sd	a3, PT_R26(sp)		# update a3 for syscall restarting
195	jr	t2
196	/* Unreached */
197
198einval:	li	v0, -EINVAL
199	jr	ra
200	END(sys32_syscall)
201
202	.align	3
203	.type	sys_call_table,@object
204sys_call_table:
205	PTR	sys32_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	sys32_execve
217	PTR	sys_chdir
218	PTR	compat_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	compat_sys_stime		/* 4025 */
231	PTR	sys32_ptrace
232	PTR	sys_alarm
233	PTR	sys_ni_syscall			/* was sys_fstat */
234	PTR	sys_pause
235	PTR	compat_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	sys_pipe
248	PTR	compat_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	compat_sys_ioctl
260	PTR	compat_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	sys32_ustat
268	PTR	sys_dup2
269	PTR	sys_getppid
270	PTR	sys_getpgrp			/* 4065 */
271	PTR	sys_setsid
272	PTR	sys32_sigaction
273	PTR	sys_sgetmask
274	PTR	sys_ssetmask
275	PTR	sys_setreuid			/* 4070 */
276	PTR	sys_setregid
277	PTR	sys32_sigsuspend
278	PTR	compat_sys_sigpending
279	PTR	sys_sethostname
280	PTR	compat_sys_setrlimit		/* 4075 */
281	PTR	compat_sys_getrlimit
282	PTR	compat_sys_getrusage
283	PTR	sys32_gettimeofday
284	PTR	sys32_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	sys32_readdir
295	PTR	old_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	compat_sys_statfs
305	PTR	compat_sys_fstatfs		/* 4100 */
306	PTR	sys_ni_syscall			/* sys_ioperm */
307	PTR	sys32_socketcall
308	PTR	sys_syslog
309	PTR	compat_sys_setitimer
310	PTR	compat_sys_getitimer		/* 4105 */
311	PTR	compat_sys_newstat
312	PTR	compat_sys_newlstat
313	PTR	compat_sys_newfstat
314	PTR	sys_uname
315	PTR	sys_ni_syscall			/* sys_ioperm  *//* 4110 */
316	PTR	sys_vhangup
317	PTR	sys_ni_syscall			/* was sys_idle	 */
318	PTR	sys_ni_syscall			/* sys_vm86 */
319	PTR	sys32_wait4
320	PTR	sys_swapoff			/* 4115 */
321	PTR	sys32_sysinfo
322	PTR	sys32_ipc
323	PTR	sys_fsync
324	PTR	sys32_sigreturn
325	PTR	sys_clone			/* 4120 */
326	PTR	sys_setdomainname
327	PTR	sys32_newuname
328	PTR	sys_ni_syscall			/* sys_modify_ldt */
329	PTR	sys32_adjtimex
330	PTR	sys_mprotect			/* 4125 */
331	PTR	compat_sys_sigprocmask
332	PTR	sys_ni_syscall			/* was creat_module */
333	PTR	sys_init_module
334	PTR	sys_delete_module
335	PTR	sys_ni_syscall			/* 4130, 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	sys32_personality
342	PTR	sys_ni_syscall	 		/* for afs_syscall */
343	PTR	sys_setfsuid
344	PTR	sys_setfsgid
345	PTR	sys32_llseek			/* 4140 */
346	PTR	sys32_getdents
347	PTR	compat_sys_select
348	PTR	sys_flock
349	PTR	sys_msync
350	PTR	compat_sys_readv		/* 4145 */
351	PTR	compat_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	sys32_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	sys32_sched_rr_get_interval 	/* 4165 */
371	PTR	compat_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	compat_sys_recvmsg
383	PTR	sys_send
384	PTR	compat_sys_sendmsg
385	PTR	sys_sendto			/* 4180 */
386	PTR	compat_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 query_module */
393	PTR	sys_poll
394	PTR	sys_nfsservctl
395	PTR	sys_setresgid			/* 4190 */
396	PTR	sys_getresgid
397	PTR	sys_prctl
398	PTR	sys32_rt_sigreturn
399	PTR	sys32_rt_sigaction
400	PTR	sys32_rt_sigprocmask 		/* 4195 */
401	PTR	sys32_rt_sigpending
402	PTR	compat_sys_rt_sigtimedwait
403	PTR	sys32_rt_sigqueueinfo
404	PTR	sys32_rt_sigsuspend
405	PTR	sys32_pread			/* 4200 */
406	PTR	sys32_pwrite
407	PTR	sys_chown
408	PTR	sys_getcwd
409	PTR	sys_capget
410	PTR	sys_capset			/* 4205 */
411	PTR	sys32_sigaltstack
412	PTR	sys32_sendfile
413	PTR	sys_ni_syscall
414	PTR	sys_ni_syscall
415	PTR	sys32_mmap2			/* 4210 */
416	PTR	sys32_truncate64
417	PTR	sys32_ftruncate64
418	PTR	sys_newstat
419	PTR	sys_newlstat
420	PTR	sys_newfstat			/* 4215 */
421	PTR	sys_pivot_root
422	PTR	sys_mincore
423	PTR	sys_madvise
424	PTR	sys_getdents64
425	PTR	compat_sys_fcntl64		/* 4220 */
426	PTR	sys_ni_syscall
427	PTR	sys_gettid
428	PTR	sys32_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	compat_sys_futex
444	PTR	compat_sys_sched_setaffinity
445	PTR	compat_sys_sched_getaffinity	/* 4240 */
446	PTR	sys_io_setup
447	PTR	sys_io_destroy
448	PTR	sys_io_getevents
449	PTR	sys_io_submit
450	PTR	sys_io_cancel			/* 4245 */
451	PTR	sys_exit_group
452	PTR	sys_lookup_dcookie
453	PTR	sys_epoll_create
454	PTR	sys_epoll_ctl
455	PTR	sys_epoll_wait			/* 4250 */
456	PTR	sys_remap_file_pages
457	PTR	sys_set_tid_address
458	PTR	sys_restart_syscall
459	PTR	sys_fadvise64_64
460	PTR	compat_sys_statfs64		/* 4255 */
461	PTR	compat_sys_fstatfs64
462	PTR	sys_timer_create
463	PTR	compat_sys_timer_settime
464	PTR	compat_sys_timer_gettime
465	PTR	sys_timer_getoverrun		/* 4260 */
466	PTR	sys_timer_delete
467	PTR	compat_sys_clock_settime
468	PTR	compat_sys_clock_gettime
469	PTR	compat_sys_clock_getres
470	PTR	compat_sys_clock_nanosleep	/* 4265 */
471	PTR	sys_tgkill
472	PTR	compat_sys_utimes
473	PTR	sys_ni_syscall			/* sys_mbind */
474	PTR	sys_ni_syscall			/* sys_get_mempolicy */
475	PTR	sys_ni_syscall			/* 4270 sys_set_mempolicy */
476	PTR	compat_sys_mq_open
477	PTR	sys_mq_unlink
478	PTR	compat_sys_mq_timedsend
479	PTR	compat_sys_mq_timedreceive
480	PTR	compat_sys_mq_notify		/* 4275 */
481	PTR	compat_sys_mq_getsetattr
482	PTR	sys_ni_syscall			/* sys_vserver */
483	PTR	sys_waitid
484	PTR	sys_ni_syscall			/* available, was setaltroot */
485	PTR	sys_add_key			/* 4280 */
486	PTR	sys_request_key
487	PTR	sys_keyctl
488	.size	sys_call_table,.-sys_call_table
489