Linux Audio

Check our new training course

Loading...
v5.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 - 2000, 2001 by Ralf Baechle
  7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  8 * Copyright (C) 2001 MIPS Technologies, Inc.
  9 * Copyright (C) 2004 Thiemo Seufer
 10 *
 11 * Hairy, the userspace application uses a different argument passing
 12 * convention than the kernel, so we have to translate things from o32
 13 * to ABI64 calling convention.	 64-bit syscalls are also processed
 14 * here for now.
 15 */
 16#include <linux/errno.h>
 17#include <asm/asm.h>
 18#include <asm/asmmacro.h>
 19#include <asm/irqflags.h>
 20#include <asm/mipsregs.h>
 21#include <asm/regdef.h>
 22#include <asm/stackframe.h>
 23#include <asm/thread_info.h>
 24#include <asm/unistd.h>
 25#include <asm/sysmips.h>
 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	ld	t1, PT_EPC(sp)		# skip syscall on return
 35
 36	dsubu	t0, v0, __NR_O32_Linux	# check syscall number
 37	sltiu	t0, t0, __NR_O32_Linux_syscalls
 38	daddiu	t1, 4			# skip to next instruction
 39	sd	t1, PT_EPC(sp)
 40	beqz	t0, not_o32_scall
 41#if 0
 42 SAVE_ALL
 43 move a1, v0
 44 PRINT("Scall %ld\n")
 45 RESTORE_ALL
 46#endif
 47
 48	/* We don't want to stumble over broken sign extensions from
 49	   userland. O32 does never use the upper half. */
 50	sll	a0, a0, 0
 51	sll	a1, a1, 0
 52	sll	a2, a2, 0
 53	sll	a3, a3, 0
 54
 55	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 56
 57	/*
 58	 * More than four arguments.  Try to deal with it by copying the
 59	 * stack arguments from the user stack to the kernel stack.
 60	 * This Sucks (TM).
 61	 *
 62	 * We intentionally keep the kernel stack a little below the top of
 63	 * userspace so we don't have to do a slower byte accurate check here.
 64	 */
 65	ld	t0, PT_R29(sp)		# get old user stack pointer
 66	daddu	t1, t0, 32
 67	bltz	t1, bad_stack
 68
 69load_a4: lw	a4, 16(t0)		# argument #5 from usp
 70load_a5: lw	a5, 20(t0)		# argument #6 from usp
 71load_a6: lw	a6, 24(t0)		# argument #7 from usp
 72load_a7: lw	a7, 28(t0)		# argument #8 from usp
 73loads_done:
 74
 75	.section __ex_table,"a"
 76	PTR	load_a4, bad_stack_a4
 77	PTR	load_a5, bad_stack_a5
 78	PTR	load_a6, bad_stack_a6
 79	PTR	load_a7, bad_stack_a7
 80	.previous
 81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 82	li	t1, _TIF_WORK_SYSCALL_ENTRY
 83	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
 84	and	t0, t1, t0
 85	bnez	t0, trace_a_syscall
 86
 87syscall_common:
 88	dsll	t0, v0, 3		# offset into table
 89	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
 90
 91	jalr	t2			# Do The Real Thing (TM)
 92
 93	li	t0, -EMAXERRNO - 1	# error?
 94	sltu	t0, t0, v0
 95	sd	t0, PT_R7(sp)		# set error flag
 96	beqz	t0, 1f
 97
 98	ld	t1, PT_R2(sp)		# syscall number
 99	dnegu	v0			# error
100	sd	t1, PT_R0(sp)		# save it for syscall restarting
1011:	sd	v0, PT_R2(sp)		# result
102
103o32_syscall_exit:
104	j	syscall_exit_partial
105
106/* ------------------------------------------------------------------------ */
107
108trace_a_syscall:
109	SAVE_STATIC
110	sd	a4, PT_R8(sp)		# Save argument registers
111	sd	a5, PT_R9(sp)
112	sd	a6, PT_R10(sp)
113	sd	a7, PT_R11(sp)		# For indirect syscalls
114
115	move	a0, sp
116	/*
117	 * absolute syscall number is in v0 unless we called syscall(__NR_###)
118	 * where the real syscall number is in a0
119	 * note: NR_syscall is the first O32 syscall but the macro is
120	 * only defined when compiling with -mabi=32 (CONFIG_32BIT)
121	 * therefore __NR_O32_Linux is used (4000)
122	 */
123	.set	push
124	.set	reorder
125	subu	t1, v0,  __NR_O32_Linux
126	move	a1, v0
127	bnez	t1, 1f /* __NR_syscall at offset 0 */
128	ld	a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
129	.set	pop
130
1311:	jal	syscall_trace_enter
132
133	bltz	v0, 1f			# seccomp failed? Skip syscall
134
135	RESTORE_STATIC
136	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
137	ld	a0, PT_R4(sp)		# Restore argument registers
138	ld	a1, PT_R5(sp)
139	ld	a2, PT_R6(sp)
140	ld	a3, PT_R7(sp)
141	ld	a4, PT_R8(sp)
142	ld	a5, PT_R9(sp)
143	ld	a6, PT_R10(sp)
144	ld	a7, PT_R11(sp)		# For indirect syscalls
145
146	dsubu	t0, v0, __NR_O32_Linux	# check (new) syscall number
147	sltiu	t0, t0, __NR_O32_Linux_syscalls
148	beqz	t0, not_o32_scall
149
150	j	syscall_common
151
1521:	j	syscall_exit
153
154/* ------------------------------------------------------------------------ */
155
156	/*
157	 * The stackpointer for a call with more than 4 arguments is bad.
158	 */
159bad_stack:
160	li	v0, EFAULT
161	sd	v0, PT_R2(sp)
162	li	t0, 1			# set error flag
163	sd	t0, PT_R7(sp)
164	j	o32_syscall_exit
165
166bad_stack_a4:
167	li	a4, 0
168	b	load_a5
169
170bad_stack_a5:
171	li	a5, 0
172	b	load_a6
173
174bad_stack_a6:
175	li	a6, 0
176	b	load_a7
177
178bad_stack_a7:
179	li	a7, 0
180	b	loads_done
181
182not_o32_scall:
183	/*
184	 * This is not an o32 compatibility syscall, pass it on
185	 * to the 64-bit syscall handlers.
186	 */
187#ifdef CONFIG_MIPS32_N32
188	j	handle_sysn32
189#else
190	j	handle_sys64
191#endif
192	END(handle_sys)
193
194LEAF(sys32_syscall)
195	subu	t0, a0, __NR_O32_Linux	# check syscall number
196	sltiu	v0, t0, __NR_O32_Linux_syscalls
197	beqz	t0, einval		# do not recurse
198	dsll	t1, t0, 3
199	beqz	v0, einval
200	ld	t2, sys32_call_table(t1)		# syscall routine
201
202	move	a0, a1			# shift argument registers
203	move	a1, a2
204	move	a2, a3
205	move	a3, a4
206	move	a4, a5
207	move	a5, a6
208	move	a6, a7
209	jr	t2
210	/* Unreached */
211
212einval: li	v0, -ENOSYS
213	jr	ra
214	END(sys32_syscall)
215
216#define __SYSCALL(nr, entry)	PTR entry
 
217	.align	3
218	.type	sys32_call_table,@object
219EXPORT(sys32_call_table)
220#include <asm/syscall_table_64_o32.h>
221#undef __SYSCALL
v6.13.7
  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 - 2000, 2001 by Ralf Baechle
  7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  8 * Copyright (C) 2001 MIPS Technologies, Inc.
  9 * Copyright (C) 2004 Thiemo Seufer
 10 *
 11 * Hairy, the userspace application uses a different argument passing
 12 * convention than the kernel, so we have to translate things from o32
 13 * to ABI64 calling convention.	 64-bit syscalls are also processed
 14 * here for now.
 15 */
 16#include <linux/errno.h>
 17#include <asm/asm.h>
 18#include <asm/asmmacro.h>
 19#include <asm/irqflags.h>
 20#include <asm/mipsregs.h>
 21#include <asm/regdef.h>
 22#include <asm/stackframe.h>
 23#include <asm/thread_info.h>
 24#include <asm/unistd.h>
 25#include <asm/sysmips.h>
 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	ld	t1, PT_EPC(sp)		# skip syscall on return
 35
 36	dsubu	t0, v0, __NR_O32_Linux	# check syscall number
 37	sltiu	t0, t0, __NR_O32_Linux_syscalls
 38	daddiu	t1, 4			# skip to next instruction
 39	sd	t1, PT_EPC(sp)
 40	beqz	t0, not_o32_scall
 41#if 0
 42 SAVE_ALL
 43 move a1, v0
 44 ASM_PRINT("Scall %ld\n")
 45 RESTORE_ALL
 46#endif
 47
 48	/* We don't want to stumble over broken sign extensions from
 49	   userland. O32 does never use the upper half. */
 50	sll	a0, a0, 0
 51	sll	a1, a1, 0
 52	sll	a2, a2, 0
 53	sll	a3, a3, 0
 54
 55	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 56
 57	/*
 58	 * More than four arguments.  Try to deal with it by copying the
 59	 * stack arguments from the user stack to the kernel stack.
 60	 * This Sucks (TM).
 61	 *
 62	 * We intentionally keep the kernel stack a little below the top of
 63	 * userspace so we don't have to do a slower byte accurate check here.
 64	 */
 65	ld	t0, PT_R29(sp)		# get old user stack pointer
 66	daddu	t1, t0, 32
 67	bltz	t1, bad_stack
 68
 69load_a4: lw	a4, 16(t0)		# argument #5 from usp
 70load_a5: lw	a5, 20(t0)		# argument #6 from usp
 71load_a6: lw	a6, 24(t0)		# argument #7 from usp
 72load_a7: lw	a7, 28(t0)		# argument #8 from usp
 73loads_done:
 74
 75	.section __ex_table,"a"
 76	PTR_WD	load_a4, bad_stack_a4
 77	PTR_WD	load_a5, bad_stack_a5
 78	PTR_WD	load_a6, bad_stack_a6
 79	PTR_WD	load_a7, bad_stack_a7
 80	.previous
 81
 82	/*
 83	 * absolute syscall number is in v0 unless we called syscall(__NR_###)
 84	 * where the real syscall number is in a0
 85	 * note: NR_syscall is the first O32 syscall but the macro is
 86	 * only defined when compiling with -mabi=32 (CONFIG_32BIT)
 87	 * therefore __NR_O32_Linux is used (4000)
 88	 */
 89
 90	subu	t2, v0,  __NR_O32_Linux
 91	bnez	t2, 1f /* __NR_syscall at offset 0 */
 92	LONG_S	a0, TI_SYSCALL($28)	# Save a0 as syscall number
 93	b	2f
 941:
 95	LONG_S	v0, TI_SYSCALL($28)	# Save v0 as syscall number
 962:
 97
 98	li	t1, _TIF_WORK_SYSCALL_ENTRY
 99	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
100	and	t0, t1, t0
101	bnez	t0, trace_a_syscall
102
103syscall_common:
104	dsll	t0, v0, 3		# offset into table
105	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
106
107	jalr	t2			# Do The Real Thing (TM)
108
109	li	t0, -EMAXERRNO - 1	# error?
110	sltu	t0, t0, v0
111	sd	t0, PT_R7(sp)		# set error flag
112	beqz	t0, 1f
113
114	ld	t1, PT_R2(sp)		# syscall number
115	dnegu	v0			# error
116	sd	t1, PT_R0(sp)		# save it for syscall restarting
1171:	sd	v0, PT_R2(sp)		# result
118
119o32_syscall_exit:
120	j	syscall_exit_partial
121
122/* ------------------------------------------------------------------------ */
123
124trace_a_syscall:
125	SAVE_STATIC
126	sd	a4, PT_R8(sp)		# Save argument registers
127	sd	a5, PT_R9(sp)
128	sd	a6, PT_R10(sp)
129	sd	a7, PT_R11(sp)		# For indirect syscalls
130
131	move	a0, sp
132	jal	syscall_trace_enter
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
134	bltz	v0, 1f			# seccomp failed? Skip syscall
135
136	RESTORE_STATIC
137	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
138	ld	a0, PT_R4(sp)		# Restore argument registers
139	ld	a1, PT_R5(sp)
140	ld	a2, PT_R6(sp)
141	ld	a3, PT_R7(sp)
142	ld	a4, PT_R8(sp)
143	ld	a5, PT_R9(sp)
144	ld	a6, PT_R10(sp)
145	ld	a7, PT_R11(sp)		# For indirect syscalls
146
147	dsubu	t0, v0, __NR_O32_Linux	# check (new) syscall number
148	sltiu	t0, t0, __NR_O32_Linux_syscalls
149	beqz	t0, not_o32_scall
150
151	j	syscall_common
152
1531:	j	syscall_exit
154
155/* ------------------------------------------------------------------------ */
156
157	/*
158	 * The stackpointer for a call with more than 4 arguments is bad.
159	 */
160bad_stack:
161	li	v0, EFAULT
162	sd	v0, PT_R2(sp)
163	li	t0, 1			# set error flag
164	sd	t0, PT_R7(sp)
165	j	o32_syscall_exit
166
167bad_stack_a4:
168	li	a4, 0
169	b	load_a5
170
171bad_stack_a5:
172	li	a5, 0
173	b	load_a6
174
175bad_stack_a6:
176	li	a6, 0
177	b	load_a7
178
179bad_stack_a7:
180	li	a7, 0
181	b	loads_done
182
183not_o32_scall:
184	/*
185	 * This is not an o32 compatibility syscall, pass it on
186	 * to the 64-bit syscall handlers.
187	 */
188#ifdef CONFIG_MIPS32_N32
189	j	handle_sysn32
190#else
191	j	handle_sys64
192#endif
193	END(handle_sys)
194
195LEAF(sys32_syscall)
196	subu	t0, a0, __NR_O32_Linux	# check syscall number
197	sltiu	v0, t0, __NR_O32_Linux_syscalls
198	beqz	t0, einval		# do not recurse
199	dsll	t1, t0, 3
200	beqz	v0, einval
201	ld	t2, sys32_call_table(t1)		# syscall routine
202
203	move	a0, a1			# shift argument registers
204	move	a1, a2
205	move	a2, a3
206	move	a3, a4
207	move	a4, a5
208	move	a5, a6
209	move	a6, a7
210	jr	t2
211	/* Unreached */
212
213einval: li	v0, -ENOSYS
214	jr	ra
215	END(sys32_syscall)
216
217#define __SYSCALL_WITH_COMPAT(nr, native, compat)	__SYSCALL(nr, compat)
218#define __SYSCALL(nr, entry)	PTR_WD entry
219	.align	3
220	.type	sys32_call_table,@object
221EXPORT(sys32_call_table)
222#include <asm/syscall_table_o32.h>