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