xref: /openbmc/linux/arch/mips/kernel/scall32-o32.S (revision 799a545b)
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	addiu	t1, 4			# skip to next instruction
39	sw	t1, PT_EPC(sp)
40
41	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
42
43	/*
44	 * More than four arguments.  Try to deal with it by copying the
45	 * stack arguments from the user stack to the kernel stack.
46	 * This Sucks (TM).
47	 */
48	lw	t0, PT_R29(sp)		# get old user stack pointer
49
50	/*
51	 * We intentionally keep the kernel stack a little below the top of
52	 * userspace so we don't have to do a slower byte accurate check here.
53	 */
54	lw	t5, TI_ADDR_LIMIT($28)
55	addu	t4, t0, 32
56	and	t5, t4
57	bltz	t5, bad_stack		# -> sp is bad
58
59	/*
60	 * Ok, copy the args from the luser stack to the kernel stack.
61	 */
62
63	.set    push
64	.set    noreorder
65	.set	nomacro
66
67load_a4: user_lw(t5, 16(t0))		# argument #5 from usp
68load_a5: user_lw(t6, 20(t0))		# argument #6 from usp
69load_a6: user_lw(t7, 24(t0))		# argument #7 from usp
70load_a7: user_lw(t8, 28(t0))		# argument #8 from usp
71loads_done:
72
73	sw	t5, 16(sp)		# argument #5 to ksp
74	sw	t6, 20(sp)		# argument #6 to ksp
75	sw	t7, 24(sp)		# argument #7 to ksp
76	sw	t8, 28(sp)		# argument #8 to ksp
77	.set	pop
78
79	.section __ex_table,"a"
80	PTR	load_a4, bad_stack_a4
81	PTR	load_a5, bad_stack_a5
82	PTR	load_a6, bad_stack_a6
83	PTR	load_a7, bad_stack_a7
84	.previous
85
86	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
87	li	t1, _TIF_WORK_SYSCALL_ENTRY
88	and	t0, t1
89	bnez	t0, syscall_trace_entry # -> yes
90syscall_common:
91	subu	v0, v0, __NR_O32_Linux	# check syscall number
92	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
93	beqz	t0, illegal_syscall
94
95	sll	t0, v0, 2
96	la	t1, sys_call_table
97	addu	t1, t0
98	lw	t2, (t1)		# syscall routine
99
100	beqz	t2, illegal_syscall
101
102	jalr	t2			# Do The Real Thing (TM)
103
104	li	t0, -EMAXERRNO - 1	# error?
105	sltu	t0, t0, v0
106	sw	t0, PT_R7(sp)		# set error flag
107	beqz	t0, 1f
108
109	lw	t1, PT_R2(sp)		# syscall number
110	negu	v0			# error
111	sw	t1, PT_R0(sp)		# save it for syscall restarting
1121:	sw	v0, PT_R2(sp)		# result
113
114o32_syscall_exit:
115	j	syscall_exit_partial
116
117/* ------------------------------------------------------------------------ */
118
119syscall_trace_entry:
120	SAVE_STATIC
121	move	a0, sp
122
123	/*
124	 * syscall number is in v0 unless we called syscall(__NR_###)
125	 * where the real syscall number is in a0
126	 */
127	move	a1, v0
128	subu	t2, v0,  __NR_O32_Linux
129	bnez	t2, 1f /* __NR_syscall at offset 0 */
130	lw	a1, PT_R4(sp)
131
1321:	jal	syscall_trace_enter
133
134	bltz	v0, 1f			# seccomp failed? Skip syscall
135
136	RESTORE_STATIC
137	lw	v0, PT_R2(sp)		# Restore syscall (maybe modified)
138	lw	a0, PT_R4(sp)		# Restore argument registers
139	lw	a1, PT_R5(sp)
140	lw	a2, PT_R6(sp)
141	lw	a3, PT_R7(sp)
142	j	syscall_common
143
1441:	j	syscall_exit
145
146/* ------------------------------------------------------------------------ */
147
148	/*
149	 * Our open-coded access area sanity test for the stack pointer
150	 * failed. We probably should handle this case a bit more drastic.
151	 */
152bad_stack:
153	li	v0, EFAULT
154	sw	v0, PT_R2(sp)
155	li	t0, 1				# set error flag
156	sw	t0, PT_R7(sp)
157	j	o32_syscall_exit
158
159bad_stack_a4:
160	li	t5, 0
161	b	load_a5
162
163bad_stack_a5:
164	li	t6, 0
165	b	load_a6
166
167bad_stack_a6:
168	li	t7, 0
169	b	load_a7
170
171bad_stack_a7:
172	li	t8, 0
173	b	loads_done
174
175	/*
176	 * The system call does not exist in this kernel
177	 */
178illegal_syscall:
179	li	v0, ENOSYS			# error
180	sw	v0, PT_R2(sp)
181	li	t0, 1				# set error flag
182	sw	t0, PT_R7(sp)
183	j	o32_syscall_exit
184	END(handle_sys)
185
186	LEAF(sys_syscall)
187	subu	t0, a0, __NR_O32_Linux	# check syscall number
188	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
189	beqz	t0, einval		# do not recurse
190	sll	t1, t0, 2
191	beqz	v0, einval
192	lw	t2, sys_call_table(t1)		# syscall routine
193	sw	a0, PT_R2(sp)			# call routine directly on restart
194
195	/* Some syscalls like execve get their arguments from struct pt_regs
196	   and claim zero arguments in the syscall table. Thus we have to
197	   assume the worst case and shuffle around all potential arguments.
198	   If you want performance, don't use indirect syscalls. */
199
200	move	a0, a1				# shift argument registers
201	move	a1, a2
202	move	a2, a3
203	lw	a3, 16(sp)
204	lw	t4, 20(sp)
205	lw	t5, 24(sp)
206	lw	t6, 28(sp)
207	sw	t4, 16(sp)
208	sw	t5, 20(sp)
209	sw	t6, 24(sp)
210	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some
211	sw	a1, PT_R5(sp)			# syscalls expect them there
212	sw	a2, PT_R6(sp)
213	sw	a3, PT_R7(sp)
214	sw	a3, PT_R26(sp)			# update a3 for syscall restarting
215	jr	t2
216	/* Unreached */
217
218einval: li	v0, -ENOSYS
219	jr	ra
220	END(sys_syscall)
221
222	.align	2
223	.type	sys_call_table, @object
224EXPORT(sys_call_table)
225	PTR	sys_syscall			/* 4000 */
226	PTR	sys_exit
227	PTR	__sys_fork
228	PTR	sys_read
229	PTR	sys_write
230	PTR	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	sys_execve
237	PTR	sys_chdir
238	PTR	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	sys_mount
247	PTR	sys_oldumount
248	PTR	sys_setuid
249	PTR	sys_getuid
250	PTR	sys_stime			/* 4025 */
251	PTR	sys_ptrace
252	PTR	sys_alarm
253	PTR	sys_ni_syscall			/* was sys_fstat */
254	PTR	sys_pause
255	PTR	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	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	sys_ioctl
280	PTR	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	sys_ustat
288	PTR	sys_dup2
289	PTR	sys_getppid
290	PTR	sys_getpgrp			/* 4065 */
291	PTR	sys_setsid
292	PTR	sys_sigaction
293	PTR	sys_sgetmask
294	PTR	sys_ssetmask
295	PTR	sys_setreuid			/* 4070 */
296	PTR	sys_setregid
297	PTR	sys_sigsuspend
298	PTR	sys_sigpending
299	PTR	sys_sethostname
300	PTR	sys_setrlimit			/* 4075 */
301	PTR	sys_getrlimit
302	PTR	sys_getrusage
303	PTR	sys_gettimeofday
304	PTR	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	sys_old_readdir
315	PTR	sys_mips_mmap			/* 4090 */
316	PTR	sys_munmap
317	PTR	sys_truncate
318	PTR	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	sys_statfs
325	PTR	sys_fstatfs			/* 4100 */
326	PTR	sys_ni_syscall			/* was ioperm(2) */
327	PTR	sys_socketcall
328	PTR	sys_syslog
329	PTR	sys_setitimer
330	PTR	sys_getitimer			/* 4105 */
331	PTR	sys_newstat
332	PTR	sys_newlstat
333	PTR	sys_newfstat
334	PTR	sys_uname
335	PTR	sys_ni_syscall			/* 4110 was iopl(2) */
336	PTR	sys_vhangup
337	PTR	sys_ni_syscall			/* was sys_idle() */
338	PTR	sys_ni_syscall			/* was sys_vm86 */
339	PTR	sys_wait4
340	PTR	sys_swapoff			/* 4115 */
341	PTR	sys_sysinfo
342	PTR	sys_ipc
343	PTR	sys_fsync
344	PTR	sys_sigreturn
345	PTR	__sys_clone			/* 4120 */
346	PTR	sys_setdomainname
347	PTR	sys_newuname
348	PTR	sys_ni_syscall			/* sys_modify_ldt */
349	PTR	sys_adjtimex
350	PTR	sys_mprotect			/* 4125 */
351	PTR	sys_sigprocmask
352	PTR	sys_ni_syscall			/* was create_module */
353	PTR	sys_init_module
354	PTR	sys_delete_module
355	PTR	sys_ni_syscall			/* 4130 was 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_personality
362	PTR	sys_ni_syscall			/* for afs_syscall */
363	PTR	sys_setfsuid
364	PTR	sys_setfsgid
365	PTR	sys_llseek			/* 4140 */
366	PTR	sys_getdents
367	PTR	sys_select
368	PTR	sys_flock
369	PTR	sys_msync
370	PTR	sys_readv			/* 4145 */
371	PTR	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	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	sys_sched_rr_get_interval	/* 4165 */
391	PTR	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	sys_getsockopt
399	PTR	sys_listen
400	PTR	sys_recv			/* 4175 */
401	PTR	sys_recvfrom
402	PTR	sys_recvmsg
403	PTR	sys_send
404	PTR	sys_sendmsg
405	PTR	sys_sendto			/* 4180 */
406	PTR	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 sys_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	sys_rt_sigreturn
419	PTR	sys_rt_sigaction
420	PTR	sys_rt_sigprocmask		/* 4195 */
421	PTR	sys_rt_sigpending
422	PTR	sys_rt_sigtimedwait
423	PTR	sys_rt_sigqueueinfo
424	PTR	sys_rt_sigsuspend
425	PTR	sys_pread64			/* 4200 */
426	PTR	sys_pwrite64
427	PTR	sys_chown
428	PTR	sys_getcwd
429	PTR	sys_capget
430	PTR	sys_capset			/* 4205 */
431	PTR	sys_sigaltstack
432	PTR	sys_sendfile
433	PTR	sys_ni_syscall
434	PTR	sys_ni_syscall
435	PTR	sys_mips_mmap2			/* 4210 */
436	PTR	sys_truncate64
437	PTR	sys_ftruncate64
438	PTR	sys_stat64
439	PTR	sys_lstat64
440	PTR	sys_fstat64			/* 4215 */
441	PTR	sys_pivot_root
442	PTR	sys_mincore
443	PTR	sys_madvise
444	PTR	sys_getdents64
445	PTR	sys_fcntl64			/* 4220 */
446	PTR	sys_ni_syscall
447	PTR	sys_gettid
448	PTR	sys_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	sys_futex
464#ifdef CONFIG_MIPS_MT_FPAFF
465	/*
466	 * For FPU affinity scheduling on MIPS MT processors, we need to
467	 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
468	 * in kernel/sched/core.c.  Considered only temporary we only support
469	 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
470	 * atm.
471	 */
472	PTR	mipsmt_sys_sched_setaffinity
473	PTR	mipsmt_sys_sched_getaffinity
474#else
475	PTR	sys_sched_setaffinity
476	PTR	sys_sched_getaffinity		/* 4240 */
477#endif /* CONFIG_MIPS_MT_FPAFF */
478	PTR	sys_io_setup
479	PTR	sys_io_destroy
480	PTR	sys_io_getevents
481	PTR	sys_io_submit
482	PTR	sys_io_cancel			/* 4245 */
483	PTR	sys_exit_group
484	PTR	sys_lookup_dcookie
485	PTR	sys_epoll_create
486	PTR	sys_epoll_ctl
487	PTR	sys_epoll_wait			/* 4250 */
488	PTR	sys_remap_file_pages
489	PTR	sys_set_tid_address
490	PTR	sys_restart_syscall
491	PTR	sys_fadvise64_64
492	PTR	sys_statfs64			/* 4255 */
493	PTR	sys_fstatfs64
494	PTR	sys_timer_create
495	PTR	sys_timer_settime
496	PTR	sys_timer_gettime
497	PTR	sys_timer_getoverrun		/* 4260 */
498	PTR	sys_timer_delete
499	PTR	sys_clock_settime
500	PTR	sys_clock_gettime
501	PTR	sys_clock_getres
502	PTR	sys_clock_nanosleep		/* 4265 */
503	PTR	sys_tgkill
504	PTR	sys_utimes
505	PTR	sys_mbind
506	PTR	sys_get_mempolicy
507	PTR	sys_set_mempolicy		/* 4270 */
508	PTR	sys_mq_open
509	PTR	sys_mq_unlink
510	PTR	sys_mq_timedsend
511	PTR	sys_mq_timedreceive
512	PTR	sys_mq_notify			/* 4275 */
513	PTR	sys_mq_getsetattr
514	PTR	sys_ni_syscall			/* sys_vserver */
515	PTR	sys_waitid
516	PTR	sys_ni_syscall			/* available, was setaltroot */
517	PTR	sys_add_key			/* 4280 */
518	PTR	sys_request_key
519	PTR	sys_keyctl
520	PTR	sys_set_thread_area
521	PTR	sys_inotify_init
522	PTR	sys_inotify_add_watch		/* 4285 */
523	PTR	sys_inotify_rm_watch
524	PTR	sys_migrate_pages
525	PTR	sys_openat
526	PTR	sys_mkdirat
527	PTR	sys_mknodat			/* 4290 */
528	PTR	sys_fchownat
529	PTR	sys_futimesat
530	PTR	sys_fstatat64
531	PTR	sys_unlinkat
532	PTR	sys_renameat			/* 4295 */
533	PTR	sys_linkat
534	PTR	sys_symlinkat
535	PTR	sys_readlinkat
536	PTR	sys_fchmodat
537	PTR	sys_faccessat			/* 4300 */
538	PTR	sys_pselect6
539	PTR	sys_ppoll
540	PTR	sys_unshare
541	PTR	sys_splice
542	PTR	sys_sync_file_range		/* 4305 */
543	PTR	sys_tee
544	PTR	sys_vmsplice
545	PTR	sys_move_pages
546	PTR	sys_set_robust_list
547	PTR	sys_get_robust_list		/* 4310 */
548	PTR	sys_kexec_load
549	PTR	sys_getcpu
550	PTR	sys_epoll_pwait
551	PTR	sys_ioprio_set
552	PTR	sys_ioprio_get			/* 4315 */
553	PTR	sys_utimensat
554	PTR	sys_signalfd
555	PTR	sys_ni_syscall			/* was timerfd */
556	PTR	sys_eventfd
557	PTR	sys_fallocate			/* 4320 */
558	PTR	sys_timerfd_create
559	PTR	sys_timerfd_gettime
560	PTR	sys_timerfd_settime
561	PTR	sys_signalfd4
562	PTR	sys_eventfd2			/* 4325 */
563	PTR	sys_epoll_create1
564	PTR	sys_dup3
565	PTR	sys_pipe2
566	PTR	sys_inotify_init1
567	PTR	sys_preadv			/* 4330 */
568	PTR	sys_pwritev
569	PTR	sys_rt_tgsigqueueinfo
570	PTR	sys_perf_event_open
571	PTR	sys_accept4
572	PTR	sys_recvmmsg			/* 4335 */
573	PTR	sys_fanotify_init
574	PTR	sys_fanotify_mark
575	PTR	sys_prlimit64
576	PTR	sys_name_to_handle_at
577	PTR	sys_open_by_handle_at		/* 4340 */
578	PTR	sys_clock_adjtime
579	PTR	sys_syncfs
580	PTR	sys_sendmmsg
581	PTR	sys_setns
582	PTR	sys_process_vm_readv		/* 4345 */
583	PTR	sys_process_vm_writev
584	PTR	sys_kcmp
585	PTR	sys_finit_module
586	PTR	sys_sched_setattr
587	PTR	sys_sched_getattr		/* 4350 */
588	PTR	sys_renameat2
589	PTR	sys_seccomp
590	PTR	sys_getrandom
591	PTR	sys_memfd_create
592	PTR	sys_bpf				/* 4355 */
593	PTR	sys_execveat
594	PTR	sys_userfaultfd
595	PTR	sys_membarrier
596	PTR	sys_mlock2
597	PTR	sys_copy_file_range		/* 4360 */
598	PTR	sys_preadv2
599	PTR	sys_pwritev2
600