aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/entry-common.S
diff options
context:
space:
mode:
authorStuart Menefy <stuart.menefy@st.com>2006-11-23 23:01:36 -0500
committerPaul Mundt <lethal@linux-sh.org>2006-12-05 20:45:38 -0500
commite0969e0c9b609fdfe217e34f3e046179ffe88eb6 (patch)
treee0769039173233ea75d4e9ed87bbcfec690dc446 /arch/sh/kernel/entry-common.S
parentc9f0b1c1410e9e637b819c5050fc8c1f1971e178 (diff)
sh: Fix syscall tracing ordering.
The implementation of system call tracing in the kernel has a couple of ordering problems: - the validity of the system call number is checked before calling out to system call tracing code, and should be done after - the system call number used when tracing is the one the system call was invoked with, while the system call tracing code can legitimatly change the call number (for example strace permutes fork into clone) This patch fixes both of these problems, and also reoders the code slightly to make the direct path through the code the common case. Signed-off-by: Stuart Menefy <stuart.menefy@st.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/entry-common.S')
-rw-r--r--arch/sh/kernel/entry-common.S45
1 files changed, 22 insertions, 23 deletions
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 5bc7fa91d095..8f96d21fcb1c 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -256,8 +256,7 @@ syscall_trace_entry:
256 mov.l @(OFF_R6,r15), r6 256 mov.l @(OFF_R6,r15), r6
257 mov.l @(OFF_R7,r15), r7 ! arg3 257 mov.l @(OFF_R7,r15), r7 ! arg3
258 mov.l @(OFF_R3,r15), r3 ! syscall_nr 258 mov.l @(OFF_R3,r15), r3 ! syscall_nr
259 ! Arrange for do_syscall_trace to be called 259 !
260 ! again as the system call returns.
261 mov.l 2f, r10 ! Number of syscalls 260 mov.l 2f, r10 ! Number of syscalls
262 cmp/hs r10, r3 261 cmp/hs r10, r3
263 bf syscall_call 262 bf syscall_call
@@ -273,6 +272,18 @@ __restore_all:
273 .align 2 272 .align 2
2741: .long restore_all 2731: .long restore_all
275 274
275 .align 2
276not_syscall_tra:
277 bra debug_trap
278 nop
279
280 .align 2
281syscall_badsys: ! Bad syscall number
282 mov #-ENOSYS, r0
283 bra resume_userspace
284 mov.l r0, @(OFF_R0,r15) ! Return value
285
286
276/* 287/*
277 * Syscall interface: 288 * Syscall interface:
278 * 289 *
@@ -316,39 +327,27 @@ ENTRY(system_call)
316 ! Is the trap argument >= 0x20? (TRA will be >= 0x80) 327 ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
317 mov #0x7f, r9 328 mov #0x7f, r9
318 cmp/hi r9, r8 329 cmp/hi r9, r8
319 bt/s 0f 330 bt/s not_syscall_tra
320 mov #OFF_TRA, r9 331 mov #OFF_TRA, r9
321 add r15, r9 332 add r15, r9
322 !
323 mov.l r8, @r9 ! set TRA value to tra 333 mov.l r8, @r9 ! set TRA value to tra
324 sti 334 sti
325 ! Call the system call handler through the table.
326 ! First check for bad syscall number
327 mov r3, r9
328 mov.l 2f, r8 ! Number of syscalls
329 cmp/hs r8, r9
330 get_current_thread_info r8, r10
331 bf good_system_call
332syscall_badsys: ! Bad syscall number
333 mov #-ENOSYS, r0
334 bra resume_userspace
335 mov.l r0, @(OFF_R0,r15) ! Return value
336 ! 335 !
3370: 336 get_current_thread_info r8, r10
338 bra debug_trap
339 nop
340 !
341good_system_call: ! Good syscall number
342 mov.l @(TI_FLAGS,r8), r8 337 mov.l @(TI_FLAGS,r8), r8
343 mov #_TIF_SYSCALL_TRACE, r10 338 mov #_TIF_SYSCALL_TRACE, r10
344 tst r10, r8 339 tst r10, r8
345 bf syscall_trace_entry 340 bf syscall_trace_entry
346 ! 341 !
342 mov.l 2f, r8 ! Number of syscalls
343 cmp/hs r8, r3
344 bt syscall_badsys
345 !
347syscall_call: 346syscall_call:
348 shll2 r9 ! x4 347 shll2 r3 ! x4
349 mov.l 3f, r8 ! Load the address of sys_call_table 348 mov.l 3f, r8 ! Load the address of sys_call_table
350 add r8, r9 349 add r8, r3
351 mov.l @r9, r8 350 mov.l @r3, r8
352 jsr @r8 ! jump to specific syscall handler 351 jsr @r8 ! jump to specific syscall handler
353 nop 352 nop
354 mov.l @(OFF_R0,r15), r12 ! save r0 353 mov.l @(OFF_R0,r15), r12 ! save r0