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