xref: /openbmc/linux/arch/mips/kernel/scall64-o32.S (revision d7a3d85e)
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/errno.h>
17#include <asm/asm.h>
18#include <asm/asmmacro.h>
19#include <asm/irqflags.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	TRACE_IRQS_ON_RELOAD
32	STI
33	.set	at
34	ld	t1, PT_EPC(sp)		# skip syscall on return
35
36	dsubu	t0, v0, __NR_O32_Linux	# check syscall number
37	sltiu	t0, t0, __NR_O32_Linux_syscalls + 1
38	daddiu	t1, 4			# skip to next instruction
39	sd	t1, PT_EPC(sp)
40	beqz	t0, not_o32_scall
41#if 0
42 SAVE_ALL
43 move a1, v0
44 PRINT("Scall %ld\n")
45 RESTORE_ALL
46#endif
47
48	/* We don't want to stumble over broken sign extensions from
49	   userland. O32 does never use the upper half. */
50	sll	a0, a0, 0
51	sll	a1, a1, 0
52	sll	a2, a2, 0
53	sll	a3, a3, 0
54
55	dsll	t0, v0, 3		# offset into table
56	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
57
58	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
59
60	/*
61	 * More than four arguments.  Try to deal with it by copying the
62	 * stack arguments from the user stack to the kernel stack.
63	 * This Sucks (TM).
64	 *
65	 * We intentionally keep the kernel stack a little below the top of
66	 * userspace so we don't have to do a slower byte accurate check here.
67	 */
68	ld	t0, PT_R29(sp)		# get old user stack pointer
69	daddu	t1, t0, 32
70	bltz	t1, bad_stack
71
721:	lw	a4, 16(t0)		# argument #5 from usp
732:	lw	a5, 20(t0)		# argument #6 from usp
743:	lw	a6, 24(t0)		# argument #7 from usp
754:	lw	a7, 28(t0)		# argument #8 from usp (for indirect syscalls)
76
77	.section __ex_table,"a"
78	PTR	1b, bad_stack
79	PTR	2b, bad_stack
80	PTR	3b, bad_stack
81	PTR	4b, bad_stack
82	.previous
83
84	li	t1, _TIF_WORK_SYSCALL_ENTRY
85	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
86	and	t0, t1, t0
87	bnez	t0, trace_a_syscall
88
89	jalr	t2			# Do The Real Thing (TM)
90
91	li	t0, -EMAXERRNO - 1	# error?
92	sltu	t0, t0, v0
93	sd	t0, PT_R7(sp)		# set error flag
94	beqz	t0, 1f
95
96	ld	t1, PT_R2(sp)		# syscall number
97	dnegu	v0			# error
98	sd	t1, PT_R0(sp)		# save it for syscall restarting
991:	sd	v0, PT_R2(sp)		# result
100
101o32_syscall_exit:
102	j	syscall_exit_partial
103
104/* ------------------------------------------------------------------------ */
105
106trace_a_syscall:
107	SAVE_STATIC
108	sd	a4, PT_R8(sp)		# Save argument registers
109	sd	a5, PT_R9(sp)
110	sd	a6, PT_R10(sp)
111	sd	a7, PT_R11(sp)		# For indirect syscalls
112
113	move	s0, t2			# Save syscall pointer
114	move	a0, sp
115	/*
116	 * absolute syscall number is in v0 unless we called syscall(__NR_###)
117	 * where the real syscall number is in a0
118	 * note: NR_syscall is the first O32 syscall but the macro is
119	 * only defined when compiling with -mabi=32 (CONFIG_32BIT)
120	 * therefore __NR_O32_Linux is used (4000)
121	 */
122	.set	push
123	.set	reorder
124	subu	t1, v0,  __NR_O32_Linux
125	move	a1, v0
126	bnez	t1, 1f /* __NR_syscall at offset 0 */
127	lw	a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
128	.set	pop
129
1301:	jal	syscall_trace_enter
131
132	bltz	v0, 2f			# seccomp failed? Skip syscall
133
134	move	t0, s0
135	RESTORE_STATIC
136	ld	a0, PT_R4(sp)		# Restore argument registers
137	ld	a1, PT_R5(sp)
138	ld	a2, PT_R6(sp)
139	ld	a3, PT_R7(sp)
140	ld	a4, PT_R8(sp)
141	ld	a5, PT_R9(sp)
142	ld	a6, PT_R10(sp)
143	ld	a7, PT_R11(sp)		# For indirect syscalls
144	jalr	t0
145
146	li	t0, -EMAXERRNO - 1	# error?
147	sltu	t0, t0, v0
148	sd	t0, PT_R7(sp)		# set error flag
149	beqz	t0, 1f
150
151	ld	t1, PT_R2(sp)		# syscall number
152	dnegu	v0			# error
153	sd	t1, PT_R0(sp)		# save it for syscall restarting
1541:	sd	v0, PT_R2(sp)		# result
155
1562:	j	syscall_exit
157
158/* ------------------------------------------------------------------------ */
159
160	/*
161	 * The stackpointer for a call with more than 4 arguments is bad.
162	 */
163bad_stack:
164	li	v0, EFAULT
165	sd	v0, PT_R2(sp)
166	li	t0, 1			# set error flag
167	sd	t0, PT_R7(sp)
168	j	o32_syscall_exit
169
170not_o32_scall:
171	/*
172	 * This is not an o32 compatibility syscall, pass it on
173	 * to the 64-bit syscall handlers.
174	 */
175#ifdef CONFIG_MIPS32_N32
176	j	handle_sysn32
177#else
178	j	handle_sys64
179#endif
180	END(handle_sys)
181
182LEAF(sys32_syscall)
183	subu	t0, a0, __NR_O32_Linux	# check syscall number
184	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
185	beqz	t0, einval		# do not recurse
186	dsll	t1, t0, 3
187	beqz	v0, einval
188	ld	t2, sys32_call_table(t1)		# syscall routine
189	sd	a0, PT_R2(sp)		# call routine directly on restart
190
191	move	a0, a1			# shift argument registers
192	move	a1, a2
193	move	a2, a3
194	move	a3, a4
195	move	a4, a5
196	move	a5, a6
197	move	a6, a7
198	sd	a0, PT_R4(sp)		# ... and push back a0 - a3, some
199	sd	a1, PT_R5(sp)		# syscalls expect them there
200	sd	a2, PT_R6(sp)
201	sd	a3, PT_R7(sp)
202	sd	a3, PT_R26(sp)		# update a3 for syscall restarting
203	jr	t2
204	/* Unreached */
205
206einval: li	v0, -ENOSYS
207	jr	ra
208	END(sys32_syscall)
209
210	.align	3
211	.type	sys32_call_table,@object
212EXPORT(sys32_call_table)
213	PTR	sys32_syscall			/* 4000 */
214	PTR	sys_exit
215	PTR	__sys_fork
216	PTR	sys_read
217	PTR	sys_write
218	PTR	compat_sys_open			/* 4005 */
219	PTR	sys_close
220	PTR	sys_waitpid
221	PTR	sys_creat
222	PTR	sys_link
223	PTR	sys_unlink			/* 4010 */
224	PTR	compat_sys_execve
225	PTR	sys_chdir
226	PTR	compat_sys_time
227	PTR	sys_mknod
228	PTR	sys_chmod			/* 4015 */
229	PTR	sys_lchown
230	PTR	sys_ni_syscall
231	PTR	sys_ni_syscall			/* was sys_stat */
232	PTR	sys_lseek
233	PTR	sys_getpid			/* 4020 */
234	PTR	compat_sys_mount
235	PTR	sys_oldumount
236	PTR	sys_setuid
237	PTR	sys_getuid
238	PTR	compat_sys_stime		/* 4025 */
239	PTR	compat_sys_ptrace
240	PTR	sys_alarm
241	PTR	sys_ni_syscall			/* was sys_fstat */
242	PTR	sys_pause
243	PTR	compat_sys_utime		/* 4030 */
244	PTR	sys_ni_syscall
245	PTR	sys_ni_syscall
246	PTR	sys_access
247	PTR	sys_nice
248	PTR	sys_ni_syscall			/* 4035 */
249	PTR	sys_sync
250	PTR	sys_kill
251	PTR	sys_rename
252	PTR	sys_mkdir
253	PTR	sys_rmdir			/* 4040 */
254	PTR	sys_dup
255	PTR	sysm_pipe
256	PTR	compat_sys_times
257	PTR	sys_ni_syscall
258	PTR	sys_brk				/* 4045 */
259	PTR	sys_setgid
260	PTR	sys_getgid
261	PTR	sys_ni_syscall			/* was signal	2 */
262	PTR	sys_geteuid
263	PTR	sys_getegid			/* 4050 */
264	PTR	sys_acct
265	PTR	sys_umount
266	PTR	sys_ni_syscall
267	PTR	compat_sys_ioctl
268	PTR	compat_sys_fcntl		/* 4055 */
269	PTR	sys_ni_syscall
270	PTR	sys_setpgid
271	PTR	sys_ni_syscall
272	PTR	sys_olduname
273	PTR	sys_umask			/* 4060 */
274	PTR	sys_chroot
275	PTR	compat_sys_ustat
276	PTR	sys_dup2
277	PTR	sys_getppid
278	PTR	sys_getpgrp			/* 4065 */
279	PTR	sys_setsid
280	PTR	sys_32_sigaction
281	PTR	sys_sgetmask
282	PTR	sys_ssetmask
283	PTR	sys_setreuid			/* 4070 */
284	PTR	sys_setregid
285	PTR	sys32_sigsuspend
286	PTR	compat_sys_sigpending
287	PTR	sys_sethostname
288	PTR	compat_sys_setrlimit		/* 4075 */
289	PTR	compat_sys_getrlimit
290	PTR	compat_sys_getrusage
291	PTR	compat_sys_gettimeofday
292	PTR	compat_sys_settimeofday
293	PTR	sys_getgroups			/* 4080 */
294	PTR	sys_setgroups
295	PTR	sys_ni_syscall			/* old_select */
296	PTR	sys_symlink
297	PTR	sys_ni_syscall			/* was sys_lstat */
298	PTR	sys_readlink			/* 4085 */
299	PTR	sys_uselib
300	PTR	sys_swapon
301	PTR	sys_reboot
302	PTR	compat_sys_old_readdir
303	PTR	sys_mips_mmap			/* 4090 */
304	PTR	sys_munmap
305	PTR	compat_sys_truncate
306	PTR	compat_sys_ftruncate
307	PTR	sys_fchmod
308	PTR	sys_fchown			/* 4095 */
309	PTR	sys_getpriority
310	PTR	sys_setpriority
311	PTR	sys_ni_syscall
312	PTR	compat_sys_statfs
313	PTR	compat_sys_fstatfs		/* 4100 */
314	PTR	sys_ni_syscall			/* sys_ioperm */
315	PTR	compat_sys_socketcall
316	PTR	sys_syslog
317	PTR	compat_sys_setitimer
318	PTR	compat_sys_getitimer		/* 4105 */
319	PTR	compat_sys_newstat
320	PTR	compat_sys_newlstat
321	PTR	compat_sys_newfstat
322	PTR	sys_uname
323	PTR	sys_ni_syscall			/* sys_ioperm  *//* 4110 */
324	PTR	sys_vhangup
325	PTR	sys_ni_syscall			/* was sys_idle	 */
326	PTR	sys_ni_syscall			/* sys_vm86 */
327	PTR	compat_sys_wait4
328	PTR	sys_swapoff			/* 4115 */
329	PTR	compat_sys_sysinfo
330	PTR	compat_sys_ipc
331	PTR	sys_fsync
332	PTR	sys32_sigreturn
333	PTR	__sys_clone			/* 4120 */
334	PTR	sys_setdomainname
335	PTR	sys_newuname
336	PTR	sys_ni_syscall			/* sys_modify_ldt */
337	PTR	compat_sys_adjtimex
338	PTR	sys_mprotect			/* 4125 */
339	PTR	compat_sys_sigprocmask
340	PTR	sys_ni_syscall			/* was creat_module */
341	PTR	sys_init_module
342	PTR	sys_delete_module
343	PTR	sys_ni_syscall			/* 4130, get_kernel_syms */
344	PTR	sys_quotactl
345	PTR	sys_getpgid
346	PTR	sys_fchdir
347	PTR	sys_bdflush
348	PTR	sys_sysfs			/* 4135 */
349	PTR	sys_32_personality
350	PTR	sys_ni_syscall			/* for afs_syscall */
351	PTR	sys_setfsuid
352	PTR	sys_setfsgid
353	PTR	sys_32_llseek			/* 4140 */
354	PTR	compat_sys_getdents
355	PTR	compat_sys_select
356	PTR	sys_flock
357	PTR	sys_msync
358	PTR	compat_sys_readv		/* 4145 */
359	PTR	compat_sys_writev
360	PTR	sys_cacheflush
361	PTR	sys_cachectl
362	PTR	sys_sysmips
363	PTR	sys_ni_syscall			/* 4150 */
364	PTR	sys_getsid
365	PTR	sys_fdatasync
366	PTR	compat_sys_sysctl
367	PTR	sys_mlock
368	PTR	sys_munlock			/* 4155 */
369	PTR	sys_mlockall
370	PTR	sys_munlockall
371	PTR	sys_sched_setparam
372	PTR	sys_sched_getparam
373	PTR	sys_sched_setscheduler		/* 4160 */
374	PTR	sys_sched_getscheduler
375	PTR	sys_sched_yield
376	PTR	sys_sched_get_priority_max
377	PTR	sys_sched_get_priority_min
378	PTR	compat_sys_sched_rr_get_interval	/* 4165 */
379	PTR	compat_sys_nanosleep
380	PTR	sys_mremap
381	PTR	sys_accept
382	PTR	sys_bind
383	PTR	sys_connect			/* 4170 */
384	PTR	sys_getpeername
385	PTR	sys_getsockname
386	PTR	sys_getsockopt
387	PTR	sys_listen
388	PTR	compat_sys_recv			/* 4175 */
389	PTR	compat_sys_recvfrom
390	PTR	compat_sys_recvmsg
391	PTR	sys_send
392	PTR	compat_sys_sendmsg
393	PTR	sys_sendto			/* 4180 */
394	PTR	compat_sys_setsockopt
395	PTR	sys_shutdown
396	PTR	sys_socket
397	PTR	sys_socketpair
398	PTR	sys_setresuid			/* 4185 */
399	PTR	sys_getresuid
400	PTR	sys_ni_syscall			/* was query_module */
401	PTR	sys_poll
402	PTR	sys_ni_syscall			/* was nfsservctl */
403	PTR	sys_setresgid			/* 4190 */
404	PTR	sys_getresgid
405	PTR	sys_prctl
406	PTR	sys32_rt_sigreturn
407	PTR	compat_sys_rt_sigaction
408	PTR	compat_sys_rt_sigprocmask	/* 4195 */
409	PTR	compat_sys_rt_sigpending
410	PTR	compat_sys_rt_sigtimedwait
411	PTR	compat_sys_rt_sigqueueinfo
412	PTR	compat_sys_rt_sigsuspend
413	PTR	sys_32_pread			/* 4200 */
414	PTR	sys_32_pwrite
415	PTR	sys_chown
416	PTR	sys_getcwd
417	PTR	sys_capget
418	PTR	sys_capset			/* 4205 */
419	PTR	compat_sys_sigaltstack
420	PTR	compat_sys_sendfile
421	PTR	sys_ni_syscall
422	PTR	sys_ni_syscall
423	PTR	sys_mips_mmap2			/* 4210 */
424	PTR	sys_32_truncate64
425	PTR	sys_32_ftruncate64
426	PTR	sys_newstat
427	PTR	sys_newlstat
428	PTR	sys_newfstat			/* 4215 */
429	PTR	sys_pivot_root
430	PTR	sys_mincore
431	PTR	sys_madvise
432	PTR	sys_getdents64
433	PTR	compat_sys_fcntl64		/* 4220 */
434	PTR	sys_ni_syscall
435	PTR	sys_gettid
436	PTR	sys32_readahead
437	PTR	sys_setxattr
438	PTR	sys_lsetxattr			/* 4225 */
439	PTR	sys_fsetxattr
440	PTR	sys_getxattr
441	PTR	sys_lgetxattr
442	PTR	sys_fgetxattr
443	PTR	sys_listxattr			/* 4230 */
444	PTR	sys_llistxattr
445	PTR	sys_flistxattr
446	PTR	sys_removexattr
447	PTR	sys_lremovexattr
448	PTR	sys_fremovexattr		/* 4235 */
449	PTR	sys_tkill
450	PTR	sys_sendfile64
451	PTR	compat_sys_futex
452	PTR	compat_sys_sched_setaffinity
453	PTR	compat_sys_sched_getaffinity	/* 4240 */
454	PTR	compat_sys_io_setup
455	PTR	sys_io_destroy
456	PTR	compat_sys_io_getevents
457	PTR	compat_sys_io_submit
458	PTR	sys_io_cancel			/* 4245 */
459	PTR	sys_exit_group
460	PTR	compat_sys_lookup_dcookie
461	PTR	sys_epoll_create
462	PTR	sys_epoll_ctl
463	PTR	sys_epoll_wait			/* 4250 */
464	PTR	sys_remap_file_pages
465	PTR	sys_set_tid_address
466	PTR	sys_restart_syscall
467	PTR	sys32_fadvise64_64
468	PTR	compat_sys_statfs64		/* 4255 */
469	PTR	compat_sys_fstatfs64
470	PTR	compat_sys_timer_create
471	PTR	compat_sys_timer_settime
472	PTR	compat_sys_timer_gettime
473	PTR	sys_timer_getoverrun		/* 4260 */
474	PTR	sys_timer_delete
475	PTR	compat_sys_clock_settime
476	PTR	compat_sys_clock_gettime
477	PTR	compat_sys_clock_getres
478	PTR	compat_sys_clock_nanosleep	/* 4265 */
479	PTR	sys_tgkill
480	PTR	compat_sys_utimes
481	PTR	compat_sys_mbind
482	PTR	compat_sys_get_mempolicy
483	PTR	compat_sys_set_mempolicy	/* 4270 */
484	PTR	compat_sys_mq_open
485	PTR	sys_mq_unlink
486	PTR	compat_sys_mq_timedsend
487	PTR	compat_sys_mq_timedreceive
488	PTR	compat_sys_mq_notify		/* 4275 */
489	PTR	compat_sys_mq_getsetattr
490	PTR	sys_ni_syscall			/* sys_vserver */
491	PTR	compat_sys_waitid
492	PTR	sys_ni_syscall			/* available, was setaltroot */
493	PTR	sys_add_key			/* 4280 */
494	PTR	sys_request_key
495	PTR	sys_keyctl
496	PTR	sys_set_thread_area
497	PTR	sys_inotify_init
498	PTR	sys_inotify_add_watch		/* 4285 */
499	PTR	sys_inotify_rm_watch
500	PTR	compat_sys_migrate_pages
501	PTR	compat_sys_openat
502	PTR	sys_mkdirat
503	PTR	sys_mknodat			/* 4290 */
504	PTR	sys_fchownat
505	PTR	compat_sys_futimesat
506	PTR	sys_newfstatat
507	PTR	sys_unlinkat
508	PTR	sys_renameat			/* 4295 */
509	PTR	sys_linkat
510	PTR	sys_symlinkat
511	PTR	sys_readlinkat
512	PTR	sys_fchmodat
513	PTR	sys_faccessat			/* 4300 */
514	PTR	compat_sys_pselect6
515	PTR	compat_sys_ppoll
516	PTR	sys_unshare
517	PTR	sys_splice
518	PTR	sys32_sync_file_range		/* 4305 */
519	PTR	sys_tee
520	PTR	compat_sys_vmsplice
521	PTR	compat_sys_move_pages
522	PTR	compat_sys_set_robust_list
523	PTR	compat_sys_get_robust_list	/* 4310 */
524	PTR	compat_sys_kexec_load
525	PTR	sys_getcpu
526	PTR	compat_sys_epoll_pwait
527	PTR	sys_ioprio_set
528	PTR	sys_ioprio_get			/* 4315 */
529	PTR	compat_sys_utimensat
530	PTR	compat_sys_signalfd
531	PTR	sys_ni_syscall			/* was timerfd */
532	PTR	sys_eventfd
533	PTR	sys32_fallocate			/* 4320 */
534	PTR	sys_timerfd_create
535	PTR	compat_sys_timerfd_gettime
536	PTR	compat_sys_timerfd_settime
537	PTR	compat_sys_signalfd4
538	PTR	sys_eventfd2			/* 4325 */
539	PTR	sys_epoll_create1
540	PTR	sys_dup3
541	PTR	sys_pipe2
542	PTR	sys_inotify_init1
543	PTR	compat_sys_preadv		/* 4330 */
544	PTR	compat_sys_pwritev
545	PTR	compat_sys_rt_tgsigqueueinfo
546	PTR	sys_perf_event_open
547	PTR	sys_accept4
548	PTR	compat_sys_recvmmsg		/* 4335 */
549	PTR	sys_fanotify_init
550	PTR	compat_sys_fanotify_mark
551	PTR	sys_prlimit64
552	PTR	sys_name_to_handle_at
553	PTR	compat_sys_open_by_handle_at	/* 4340 */
554	PTR	compat_sys_clock_adjtime
555	PTR	sys_syncfs
556	PTR	compat_sys_sendmmsg
557	PTR	sys_setns
558	PTR	compat_sys_process_vm_readv	/* 4345 */
559	PTR	compat_sys_process_vm_writev
560	PTR	sys_kcmp
561	PTR	sys_finit_module
562	PTR	sys_sched_setattr
563	PTR	sys_sched_getattr		/* 4350 */
564	PTR	sys_renameat2
565	PTR	sys_seccomp
566	PTR	sys_getrandom
567	PTR	sys_memfd_create
568	PTR	sys_bpf				/* 4355 */
569	PTR	compat_sys_execveat
570	.size	sys32_call_table,.-sys32_call_table
571