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