xref: /openbmc/linux/arch/mips/kernel/scall32-o32.S (revision 92a2c6b2)
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-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org>
7 * Copyright (C) 2001 MIPS Technologies, Inc.
8 * Copyright (C) 2004 Thiemo Seufer
9 * Copyright (C) 2014 Imagination Technologies Ltd.
10 */
11#include <linux/errno.h>
12#include <asm/asm.h>
13#include <asm/asmmacro.h>
14#include <asm/irqflags.h>
15#include <asm/mipsregs.h>
16#include <asm/regdef.h>
17#include <asm/stackframe.h>
18#include <asm/isadep.h>
19#include <asm/sysmips.h>
20#include <asm/thread_info.h>
21#include <asm/unistd.h>
22#include <asm/war.h>
23#include <asm/asm-offsets.h>
24
25/* Highest syscall used of any syscall flavour */
26#define MAX_SYSCALL_NO	__NR_O32_Linux + __NR_O32_Linux_syscalls
27
28	.align	5
29NESTED(handle_sys, PT_SIZE, sp)
30	.set	noat
31	SAVE_SOME
32	TRACE_IRQS_ON_RELOAD
33	STI
34	.set	at
35
36	lw	t1, PT_EPC(sp)		# skip syscall on return
37
38	subu	v0, v0, __NR_O32_Linux	# check syscall number
39	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
40	addiu	t1, 4			# skip to next instruction
41	sw	t1, PT_EPC(sp)
42	beqz	t0, illegal_syscall
43
44	sll	t0, v0, 2
45	la	t1, sys_call_table
46	addu	t1, t0
47	lw	t2, (t1)		# syscall routine
48	beqz	t2, illegal_syscall
49
50	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
51
52	/*
53	 * More than four arguments.  Try to deal with it by copying the
54	 * stack arguments from the user stack to the kernel stack.
55	 * This Sucks (TM).
56	 */
57	lw	t0, PT_R29(sp)		# get old user stack pointer
58
59	/*
60	 * We intentionally keep the kernel stack a little below the top of
61	 * userspace so we don't have to do a slower byte accurate check here.
62	 */
63	lw	t5, TI_ADDR_LIMIT($28)
64	addu	t4, t0, 32
65	and	t5, t4
66	bltz	t5, bad_stack		# -> sp is bad
67
68	/*
69	 * Ok, copy the args from the luser stack to the kernel stack.
70	 */
71
72	.set    push
73	.set    noreorder
74	.set	nomacro
75
761:	user_lw(t5, 16(t0))		# argument #5 from usp
774:	user_lw(t6, 20(t0))		# argument #6 from usp
783:	user_lw(t7, 24(t0))		# argument #7 from usp
792:	user_lw(t8, 28(t0))		# argument #8 from usp
80
81	sw	t5, 16(sp)		# argument #5 to ksp
82	sw	t6, 20(sp)		# argument #6 to ksp
83	sw	t7, 24(sp)		# argument #7 to ksp
84	sw	t8, 28(sp)		# argument #8 to ksp
85	.set	pop
86
87	.section __ex_table,"a"
88	PTR	1b,bad_stack
89	PTR	2b,bad_stack
90	PTR	3b,bad_stack
91	PTR	4b,bad_stack
92	.previous
93
94	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
95	li	t1, _TIF_WORK_SYSCALL_ENTRY
96	and	t0, t1
97	bnez	t0, syscall_trace_entry # -> yes
98
99	jalr	t2			# Do The Real Thing (TM)
100
101	li	t0, -EMAXERRNO - 1	# error?
102	sltu	t0, t0, v0
103	sw	t0, PT_R7(sp)		# set error flag
104	beqz	t0, 1f
105
106	lw	t1, PT_R2(sp)		# syscall number
107	negu	v0			# error
108	sw	t1, PT_R0(sp)		# save it for syscall restarting
1091:	sw	v0, PT_R2(sp)		# result
110
111o32_syscall_exit:
112	j	syscall_exit_partial
113
114/* ------------------------------------------------------------------------ */
115
116syscall_trace_entry:
117	SAVE_STATIC
118	move	s0, t2
119	move	a0, sp
120
121	/*
122	 * syscall number is in v0 unless we called syscall(__NR_###)
123	 * where the real syscall number is in a0
124	 */
125	addiu	a1, v0,  __NR_O32_Linux
126	bnez	v0, 1f /* __NR_syscall at offset 0 */
127	lw	a1, PT_R4(sp)
128
1291:	jal	syscall_trace_enter
130
131	bltz	v0, 2f			# seccomp failed? Skip syscall
132
133	move	t0, s0
134	RESTORE_STATIC
135	lw	a0, PT_R4(sp)		# Restore argument registers
136	lw	a1, PT_R5(sp)
137	lw	a2, PT_R6(sp)
138	lw	a3, PT_R7(sp)
139	jalr	t0
140
141	li	t0, -EMAXERRNO - 1	# error?
142	sltu	t0, t0, v0
143	sw	t0, PT_R7(sp)		# set error flag
144	beqz	t0, 1f
145
146	lw	t1, PT_R2(sp)		# syscall number
147	negu	v0			# error
148	sw	t1, PT_R0(sp)		# save it for syscall restarting
1491:	sw	v0, PT_R2(sp)		# result
150
1512:	j	syscall_exit
152
153/* ------------------------------------------------------------------------ */
154
155	/*
156	 * The stackpointer for a call with more than 4 arguments is bad.
157	 * We probably should handle this case a bit more drastic.
158	 */
159bad_stack:
160	li	v0, EFAULT
161	sw	v0, PT_R2(sp)
162	li	t0, 1				# set error flag
163	sw	t0, PT_R7(sp)
164	j	o32_syscall_exit
165
166	/*
167	 * The system call does not exist in this kernel
168	 */
169illegal_syscall:
170	li	v0, ENOSYS			# error
171	sw	v0, PT_R2(sp)
172	li	t0, 1				# set error flag
173	sw	t0, PT_R7(sp)
174	j	o32_syscall_exit
175	END(handle_sys)
176
177	LEAF(sys_syscall)
178	subu	t0, a0, __NR_O32_Linux	# check syscall number
179	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
180	beqz	t0, einval		# do not recurse
181	sll	t1, t0, 2
182	beqz	v0, einval
183	lw	t2, sys_call_table(t1)		# syscall routine
184	sw	a0, PT_R2(sp)			# call routine directly on restart
185
186	/* Some syscalls like execve get their arguments from struct pt_regs
187	   and claim zero arguments in the syscall table. Thus we have to
188	   assume the worst case and shuffle around all potential arguments.
189	   If you want performance, don't use indirect syscalls. */
190
191	move	a0, a1				# shift argument registers
192	move	a1, a2
193	move	a2, a3
194	lw	a3, 16(sp)
195	lw	t4, 20(sp)
196	lw	t5, 24(sp)
197	lw	t6, 28(sp)
198	sw	t4, 16(sp)
199	sw	t5, 20(sp)
200	sw	t6, 24(sp)
201	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some
202	sw	a1, PT_R5(sp)			# syscalls expect them there
203	sw	a2, PT_R6(sp)
204	sw	a3, PT_R7(sp)
205	sw	a3, PT_R26(sp)			# update a3 for syscall restarting
206	jr	t2
207	/* Unreached */
208
209einval: li	v0, -ENOSYS
210	jr	ra
211	END(sys_syscall)
212
213	.align	2
214	.type	sys_call_table, @object
215EXPORT(sys_call_table)
216	PTR	sys_syscall			/* 4000 */
217	PTR	sys_exit
218	PTR	__sys_fork
219	PTR	sys_read
220	PTR	sys_write
221	PTR	sys_open			/* 4005 */
222	PTR	sys_close
223	PTR	sys_waitpid
224	PTR	sys_creat
225	PTR	sys_link
226	PTR	sys_unlink			/* 4010 */
227	PTR	sys_execve
228	PTR	sys_chdir
229	PTR	sys_time
230	PTR	sys_mknod
231	PTR	sys_chmod			/* 4015 */
232	PTR	sys_lchown
233	PTR	sys_ni_syscall
234	PTR	sys_ni_syscall			/* was sys_stat */
235	PTR	sys_lseek
236	PTR	sys_getpid			/* 4020 */
237	PTR	sys_mount
238	PTR	sys_oldumount
239	PTR	sys_setuid
240	PTR	sys_getuid
241	PTR	sys_stime			/* 4025 */
242	PTR	sys_ptrace
243	PTR	sys_alarm
244	PTR	sys_ni_syscall			/* was sys_fstat */
245	PTR	sys_pause
246	PTR	sys_utime			/* 4030 */
247	PTR	sys_ni_syscall
248	PTR	sys_ni_syscall
249	PTR	sys_access
250	PTR	sys_nice
251	PTR	sys_ni_syscall			/* 4035 */
252	PTR	sys_sync
253	PTR	sys_kill
254	PTR	sys_rename
255	PTR	sys_mkdir
256	PTR	sys_rmdir			/* 4040 */
257	PTR	sys_dup
258	PTR	sysm_pipe
259	PTR	sys_times
260	PTR	sys_ni_syscall
261	PTR	sys_brk				/* 4045 */
262	PTR	sys_setgid
263	PTR	sys_getgid
264	PTR	sys_ni_syscall			/* was signal(2) */
265	PTR	sys_geteuid
266	PTR	sys_getegid			/* 4050 */
267	PTR	sys_acct
268	PTR	sys_umount
269	PTR	sys_ni_syscall
270	PTR	sys_ioctl
271	PTR	sys_fcntl			/* 4055 */
272	PTR	sys_ni_syscall
273	PTR	sys_setpgid
274	PTR	sys_ni_syscall
275	PTR	sys_olduname
276	PTR	sys_umask			/* 4060 */
277	PTR	sys_chroot
278	PTR	sys_ustat
279	PTR	sys_dup2
280	PTR	sys_getppid
281	PTR	sys_getpgrp			/* 4065 */
282	PTR	sys_setsid
283	PTR	sys_sigaction
284	PTR	sys_sgetmask
285	PTR	sys_ssetmask
286	PTR	sys_setreuid			/* 4070 */
287	PTR	sys_setregid
288	PTR	sys_sigsuspend
289	PTR	sys_sigpending
290	PTR	sys_sethostname
291	PTR	sys_setrlimit			/* 4075 */
292	PTR	sys_getrlimit
293	PTR	sys_getrusage
294	PTR	sys_gettimeofday
295	PTR	sys_settimeofday
296	PTR	sys_getgroups			/* 4080 */
297	PTR	sys_setgroups
298	PTR	sys_ni_syscall			/* old_select */
299	PTR	sys_symlink
300	PTR	sys_ni_syscall			/* was sys_lstat */
301	PTR	sys_readlink			/* 4085 */
302	PTR	sys_uselib
303	PTR	sys_swapon
304	PTR	sys_reboot
305	PTR	sys_old_readdir
306	PTR	sys_mips_mmap			/* 4090 */
307	PTR	sys_munmap
308	PTR	sys_truncate
309	PTR	sys_ftruncate
310	PTR	sys_fchmod
311	PTR	sys_fchown			/* 4095 */
312	PTR	sys_getpriority
313	PTR	sys_setpriority
314	PTR	sys_ni_syscall
315	PTR	sys_statfs
316	PTR	sys_fstatfs			/* 4100 */
317	PTR	sys_ni_syscall			/* was ioperm(2) */
318	PTR	sys_socketcall
319	PTR	sys_syslog
320	PTR	sys_setitimer
321	PTR	sys_getitimer			/* 4105 */
322	PTR	sys_newstat
323	PTR	sys_newlstat
324	PTR	sys_newfstat
325	PTR	sys_uname
326	PTR	sys_ni_syscall			/* 4110 was iopl(2) */
327	PTR	sys_vhangup
328	PTR	sys_ni_syscall			/* was sys_idle() */
329	PTR	sys_ni_syscall			/* was sys_vm86 */
330	PTR	sys_wait4
331	PTR	sys_swapoff			/* 4115 */
332	PTR	sys_sysinfo
333	PTR	sys_ipc
334	PTR	sys_fsync
335	PTR	sys_sigreturn
336	PTR	__sys_clone			/* 4120 */
337	PTR	sys_setdomainname
338	PTR	sys_newuname
339	PTR	sys_ni_syscall			/* sys_modify_ldt */
340	PTR	sys_adjtimex
341	PTR	sys_mprotect			/* 4125 */
342	PTR	sys_sigprocmask
343	PTR	sys_ni_syscall			/* was create_module */
344	PTR	sys_init_module
345	PTR	sys_delete_module
346	PTR	sys_ni_syscall			/* 4130 was get_kernel_syms */
347	PTR	sys_quotactl
348	PTR	sys_getpgid
349	PTR	sys_fchdir
350	PTR	sys_bdflush
351	PTR	sys_sysfs			/* 4135 */
352	PTR	sys_personality
353	PTR	sys_ni_syscall			/* for afs_syscall */
354	PTR	sys_setfsuid
355	PTR	sys_setfsgid
356	PTR	sys_llseek			/* 4140 */
357	PTR	sys_getdents
358	PTR	sys_select
359	PTR	sys_flock
360	PTR	sys_msync
361	PTR	sys_readv			/* 4145 */
362	PTR	sys_writev
363	PTR	sys_cacheflush
364	PTR	sys_cachectl
365	PTR	sys_sysmips
366	PTR	sys_ni_syscall			/* 4150 */
367	PTR	sys_getsid
368	PTR	sys_fdatasync
369	PTR	sys_sysctl
370	PTR	sys_mlock
371	PTR	sys_munlock			/* 4155 */
372	PTR	sys_mlockall
373	PTR	sys_munlockall
374	PTR	sys_sched_setparam
375	PTR	sys_sched_getparam
376	PTR	sys_sched_setscheduler		/* 4160 */
377	PTR	sys_sched_getscheduler
378	PTR	sys_sched_yield
379	PTR	sys_sched_get_priority_max
380	PTR	sys_sched_get_priority_min
381	PTR	sys_sched_rr_get_interval	/* 4165 */
382	PTR	sys_nanosleep
383	PTR	sys_mremap
384	PTR	sys_accept
385	PTR	sys_bind
386	PTR	sys_connect			/* 4170 */
387	PTR	sys_getpeername
388	PTR	sys_getsockname
389	PTR	sys_getsockopt
390	PTR	sys_listen
391	PTR	sys_recv			/* 4175 */
392	PTR	sys_recvfrom
393	PTR	sys_recvmsg
394	PTR	sys_send
395	PTR	sys_sendmsg
396	PTR	sys_sendto			/* 4180 */
397	PTR	sys_setsockopt
398	PTR	sys_shutdown
399	PTR	sys_socket
400	PTR	sys_socketpair
401	PTR	sys_setresuid			/* 4185 */
402	PTR	sys_getresuid
403	PTR	sys_ni_syscall			/* was sys_query_module */
404	PTR	sys_poll
405	PTR	sys_ni_syscall			/* was nfsservctl */
406	PTR	sys_setresgid			/* 4190 */
407	PTR	sys_getresgid
408	PTR	sys_prctl
409	PTR	sys_rt_sigreturn
410	PTR	sys_rt_sigaction
411	PTR	sys_rt_sigprocmask		/* 4195 */
412	PTR	sys_rt_sigpending
413	PTR	sys_rt_sigtimedwait
414	PTR	sys_rt_sigqueueinfo
415	PTR	sys_rt_sigsuspend
416	PTR	sys_pread64			/* 4200 */
417	PTR	sys_pwrite64
418	PTR	sys_chown
419	PTR	sys_getcwd
420	PTR	sys_capget
421	PTR	sys_capset			/* 4205 */
422	PTR	sys_sigaltstack
423	PTR	sys_sendfile
424	PTR	sys_ni_syscall
425	PTR	sys_ni_syscall
426	PTR	sys_mips_mmap2			/* 4210 */
427	PTR	sys_truncate64
428	PTR	sys_ftruncate64
429	PTR	sys_stat64
430	PTR	sys_lstat64
431	PTR	sys_fstat64			/* 4215 */
432	PTR	sys_pivot_root
433	PTR	sys_mincore
434	PTR	sys_madvise
435	PTR	sys_getdents64
436	PTR	sys_fcntl64			/* 4220 */
437	PTR	sys_ni_syscall
438	PTR	sys_gettid
439	PTR	sys_readahead
440	PTR	sys_setxattr
441	PTR	sys_lsetxattr			/* 4225 */
442	PTR	sys_fsetxattr
443	PTR	sys_getxattr
444	PTR	sys_lgetxattr
445	PTR	sys_fgetxattr
446	PTR	sys_listxattr			/* 4230 */
447	PTR	sys_llistxattr
448	PTR	sys_flistxattr
449	PTR	sys_removexattr
450	PTR	sys_lremovexattr
451	PTR	sys_fremovexattr		/* 4235 */
452	PTR	sys_tkill
453	PTR	sys_sendfile64
454	PTR	sys_futex
455#ifdef CONFIG_MIPS_MT_FPAFF
456	/*
457	 * For FPU affinity scheduling on MIPS MT processors, we need to
458	 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
459	 * in kernel/sched/core.c.  Considered only temporary we only support
460	 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
461	 * atm.
462	 */
463	PTR	mipsmt_sys_sched_setaffinity
464	PTR	mipsmt_sys_sched_getaffinity
465#else
466	PTR	sys_sched_setaffinity
467	PTR	sys_sched_getaffinity		/* 4240 */
468#endif /* CONFIG_MIPS_MT_FPAFF */
469	PTR	sys_io_setup
470	PTR	sys_io_destroy
471	PTR	sys_io_getevents
472	PTR	sys_io_submit
473	PTR	sys_io_cancel			/* 4245 */
474	PTR	sys_exit_group
475	PTR	sys_lookup_dcookie
476	PTR	sys_epoll_create
477	PTR	sys_epoll_ctl
478	PTR	sys_epoll_wait			/* 4250 */
479	PTR	sys_remap_file_pages
480	PTR	sys_set_tid_address
481	PTR	sys_restart_syscall
482	PTR	sys_fadvise64_64
483	PTR	sys_statfs64			/* 4255 */
484	PTR	sys_fstatfs64
485	PTR	sys_timer_create
486	PTR	sys_timer_settime
487	PTR	sys_timer_gettime
488	PTR	sys_timer_getoverrun		/* 4260 */
489	PTR	sys_timer_delete
490	PTR	sys_clock_settime
491	PTR	sys_clock_gettime
492	PTR	sys_clock_getres
493	PTR	sys_clock_nanosleep		/* 4265 */
494	PTR	sys_tgkill
495	PTR	sys_utimes
496	PTR	sys_mbind
497	PTR	sys_get_mempolicy
498	PTR	sys_set_mempolicy		/* 4270 */
499	PTR	sys_mq_open
500	PTR	sys_mq_unlink
501	PTR	sys_mq_timedsend
502	PTR	sys_mq_timedreceive
503	PTR	sys_mq_notify			/* 4275 */
504	PTR	sys_mq_getsetattr
505	PTR	sys_ni_syscall			/* sys_vserver */
506	PTR	sys_waitid
507	PTR	sys_ni_syscall			/* available, was setaltroot */
508	PTR	sys_add_key			/* 4280 */
509	PTR	sys_request_key
510	PTR	sys_keyctl
511	PTR	sys_set_thread_area
512	PTR	sys_inotify_init
513	PTR	sys_inotify_add_watch		/* 4285 */
514	PTR	sys_inotify_rm_watch
515	PTR	sys_migrate_pages
516	PTR	sys_openat
517	PTR	sys_mkdirat
518	PTR	sys_mknodat			/* 4290 */
519	PTR	sys_fchownat
520	PTR	sys_futimesat
521	PTR	sys_fstatat64
522	PTR	sys_unlinkat
523	PTR	sys_renameat			/* 4295 */
524	PTR	sys_linkat
525	PTR	sys_symlinkat
526	PTR	sys_readlinkat
527	PTR	sys_fchmodat
528	PTR	sys_faccessat			/* 4300 */
529	PTR	sys_pselect6
530	PTR	sys_ppoll
531	PTR	sys_unshare
532	PTR	sys_splice
533	PTR	sys_sync_file_range		/* 4305 */
534	PTR	sys_tee
535	PTR	sys_vmsplice
536	PTR	sys_move_pages
537	PTR	sys_set_robust_list
538	PTR	sys_get_robust_list		/* 4310 */
539	PTR	sys_kexec_load
540	PTR	sys_getcpu
541	PTR	sys_epoll_pwait
542	PTR	sys_ioprio_set
543	PTR	sys_ioprio_get			/* 4315 */
544	PTR	sys_utimensat
545	PTR	sys_signalfd
546	PTR	sys_ni_syscall			/* was timerfd */
547	PTR	sys_eventfd
548	PTR	sys_fallocate			/* 4320 */
549	PTR	sys_timerfd_create
550	PTR	sys_timerfd_gettime
551	PTR	sys_timerfd_settime
552	PTR	sys_signalfd4
553	PTR	sys_eventfd2			/* 4325 */
554	PTR	sys_epoll_create1
555	PTR	sys_dup3
556	PTR	sys_pipe2
557	PTR	sys_inotify_init1
558	PTR	sys_preadv			/* 4330 */
559	PTR	sys_pwritev
560	PTR	sys_rt_tgsigqueueinfo
561	PTR	sys_perf_event_open
562	PTR	sys_accept4
563	PTR	sys_recvmmsg			/* 4335 */
564	PTR	sys_fanotify_init
565	PTR	sys_fanotify_mark
566	PTR	sys_prlimit64
567	PTR	sys_name_to_handle_at
568	PTR	sys_open_by_handle_at		/* 4340 */
569	PTR	sys_clock_adjtime
570	PTR	sys_syncfs
571	PTR	sys_sendmmsg
572	PTR	sys_setns
573	PTR	sys_process_vm_readv		/* 4345 */
574	PTR	sys_process_vm_writev
575	PTR	sys_kcmp
576	PTR	sys_finit_module
577	PTR	sys_sched_setattr
578	PTR	sys_sched_getattr		/* 4350 */
579	PTR	sys_renameat2
580	PTR	sys_seccomp
581	PTR	sys_getrandom
582	PTR	sys_memfd_create
583	PTR	sys_bpf				/* 4355 */
584	PTR	sys_execveat
585