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