aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2008-11-27 05:05:55 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-11-27 05:06:56 -0500
commit59da21398e680e8100625d689c8bebee6a139e93 (patch)
tree7d93f87d2942dac06367af8b3a269e9f6d557b29 /arch/s390/kernel/entry.S
parented313489badef16d700f5a3be50e8fd8f8294bc8 (diff)
[S390] fix system call parameter functions.
syscall_get_nr() currently returns a valid result only if the call chain of the traced process includes do_syscall_trace_enter(). But collect_syscall() can be called for any sleeping task, the result of syscall_get_nr() in general is completely bogus. To make syscall_get_nr() work for any sleeping task the traps field in pt_regs is replace with svcnr - the system call number the process is executing. If svcnr == 0 the process is not on a system call path. The syscall_get_arguments and syscall_set_arguments use regs->gprs[2] for the first system call parameter. This is incorrect since gprs[2] may have been overwritten with the system call number if the call chain includes do_syscall_trace_enter. Use regs->orig_gprs2 instead. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S21
1 files changed, 11 insertions, 10 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 08844fc24a2e..198ea18a534d 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -46,7 +46,7 @@ SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56
46SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 46SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60
47SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 47SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
48SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC 48SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
49SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP 49SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR
50SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE 50SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
51 51
52_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 52_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
@@ -183,11 +183,10 @@ STACK_SIZE = 1 << STACK_SHIFT
183 .macro CREATE_STACK_FRAME psworg,savearea 183 .macro CREATE_STACK_FRAME psworg,savearea
184 s %r15,BASED(.Lc_spsize) # make room for registers & psw 184 s %r15,BASED(.Lc_spsize) # make room for registers & psw
185 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 185 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
186 la %r12,\psworg
187 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 186 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
188 icm %r12,12,__LC_SVC_ILC 187 icm %r12,3,__LC_SVC_ILC
189 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 188 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
190 st %r12,SP_ILC(%r15) 189 st %r12,SP_SVCNR(%r15)
191 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack 190 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
192 la %r12,0 191 la %r12,0
193 st %r12,__SF_BACKCHAIN(%r15) # clear back chain 192 st %r12,__SF_BACKCHAIN(%r15) # clear back chain
@@ -264,16 +263,17 @@ sysc_update:
264#endif 263#endif
265sysc_do_svc: 264sysc_do_svc:
266 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 265 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
267 sla %r7,2 # *4 and test for svc 0 266 ltr %r7,%r7 # test for svc 0
268 bnz BASED(sysc_nr_ok) # svc number > 0 267 bnz BASED(sysc_nr_ok) # svc number > 0
269 # svc 0: system call number in %r1 268 # svc 0: system call number in %r1
270 cl %r1,BASED(.Lnr_syscalls) 269 cl %r1,BASED(.Lnr_syscalls)
271 bnl BASED(sysc_nr_ok) 270 bnl BASED(sysc_nr_ok)
272 lr %r7,%r1 # copy svc number to %r7 271 lr %r7,%r1 # copy svc number to %r7
273 sla %r7,2 # *4
274sysc_nr_ok: 272sysc_nr_ok:
275 mvc SP_ARGS(4,%r15),SP_R7(%r15) 273 mvc SP_ARGS(4,%r15),SP_R7(%r15)
276sysc_do_restart: 274sysc_do_restart:
275 sth %r7,SP_SVCNR(%r15)
276 sll %r7,2 # svc number *4
277 l %r8,BASED(.Lsysc_table) 277 l %r8,BASED(.Lsysc_table)
278 tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) 278 tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
279 l %r8,0(%r7,%r8) # get system call addr. 279 l %r8,0(%r7,%r8) # get system call addr.
@@ -376,7 +376,6 @@ sysc_notify_resume:
376sysc_restart: 376sysc_restart:
377 ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC 377 ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
378 l %r7,SP_R2(%r15) # load new svc number 378 l %r7,SP_R2(%r15) # load new svc number
379 sla %r7,2
380 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument 379 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
381 lm %r2,%r6,SP_R2(%r15) # load svc arguments 380 lm %r2,%r6,SP_R2(%r15) # load svc arguments
382 b BASED(sysc_do_restart) # restart svc 381 b BASED(sysc_do_restart) # restart svc
@@ -386,7 +385,8 @@ sysc_restart:
386# 385#
387sysc_singlestep: 386sysc_singlestep:
388 ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP 387 ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
389 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check 388 mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
389 mvi SP_SVCNR+1(%r15),0xff
390 la %r2,SP_PTREGS(%r15) # address of register-save area 390 la %r2,SP_PTREGS(%r15) # address of register-save area
391 l %r1,BASED(.Lhandle_per) # load adr. of per handler 391 l %r1,BASED(.Lhandle_per) # load adr. of per handler
392 la %r14,BASED(sysc_return) # load adr. of system return 392 la %r14,BASED(sysc_return) # load adr. of system return
@@ -407,7 +407,7 @@ sysc_tracesys:
407 bnl BASED(sysc_tracenogo) 407 bnl BASED(sysc_tracenogo)
408 l %r8,BASED(.Lsysc_table) 408 l %r8,BASED(.Lsysc_table)
409 lr %r7,%r2 409 lr %r7,%r2
410 sll %r7,2 # *4 410 sll %r7,2 # svc number *4
411 l %r8,0(%r7,%r8) 411 l %r8,0(%r7,%r8)
412sysc_tracego: 412sysc_tracego:
413 lm %r3,%r6,SP_R3(%r15) 413 lm %r3,%r6,SP_R3(%r15)
@@ -586,7 +586,8 @@ pgm_svcper:
586# per was called from kernel, must be kprobes 586# per was called from kernel, must be kprobes
587# 587#
588kernel_per: 588kernel_per:
589 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check 589 mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
590 mvi SP_SVCNR+1(%r15),0xff
590 la %r2,SP_PTREGS(%r15) # address of register-save area 591 la %r2,SP_PTREGS(%r15) # address of register-save area
591 l %r1,BASED(.Lhandle_per) # load adr. of per handler 592 l %r1,BASED(.Lhandle_per) # load adr. of per handler
592 la %r14,BASED(sysc_restore)# load adr. of system return 593 la %r14,BASED(sysc_restore)# load adr. of system return