Linux Audio

Check our new training course

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