[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>
This commit is contained in:
@ -46,7 +46,7 @@ SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112
|
||||
SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120
|
||||
SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
|
||||
SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
|
||||
SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
|
||||
SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR
|
||||
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
|
||||
|
||||
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
|
||||
@ -171,11 +171,10 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
|
||||
.macro CREATE_STACK_FRAME psworg,savearea
|
||||
aghi %r15,-SP_SIZE # make room for registers & psw
|
||||
mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
|
||||
la %r12,\psworg
|
||||
stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
|
||||
icm %r12,12,__LC_SVC_ILC
|
||||
icm %r12,3,__LC_SVC_ILC
|
||||
stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
|
||||
st %r12,SP_ILC(%r15)
|
||||
st %r12,SP_SVCNR(%r15)
|
||||
mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack
|
||||
la %r12,0
|
||||
stg %r12,__SF_BACKCHAIN(%r15)
|
||||
@ -250,16 +249,17 @@ sysc_update:
|
||||
#endif
|
||||
sysc_do_svc:
|
||||
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||
slag %r7,%r7,2 # *4 and test for svc 0
|
||||
ltgr %r7,%r7 # test for svc 0
|
||||
jnz sysc_nr_ok
|
||||
# svc 0: system call number in %r1
|
||||
cl %r1,BASED(.Lnr_syscalls)
|
||||
jnl sysc_nr_ok
|
||||
lgfr %r7,%r1 # clear high word in r1
|
||||
slag %r7,%r7,2 # svc 0: system call number in %r1
|
||||
sysc_nr_ok:
|
||||
mvc SP_ARGS(8,%r15),SP_R7(%r15)
|
||||
sysc_do_restart:
|
||||
sth %r7,SP_SVCNR(%r15)
|
||||
sllg %r7,%r7,2 # svc number * 4
|
||||
larl %r10,sys_call_table
|
||||
#ifdef CONFIG_COMPAT
|
||||
tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ?
|
||||
@ -363,7 +363,6 @@ sysc_notify_resume:
|
||||
sysc_restart:
|
||||
ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
|
||||
lg %r7,SP_R2(%r15) # load new svc number
|
||||
slag %r7,%r7,2 # *4
|
||||
mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument
|
||||
lmg %r2,%r6,SP_R2(%r15) # load svc arguments
|
||||
j sysc_do_restart # restart svc
|
||||
@ -372,9 +371,8 @@ sysc_restart:
|
||||
# _TIF_SINGLE_STEP is set, call do_single_step
|
||||
#
|
||||
sysc_singlestep:
|
||||
ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
|
||||
lhi %r0,__LC_PGM_OLD_PSW
|
||||
sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
|
||||
ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
|
||||
xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
|
||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||
larl %r14,sysc_return # load adr. of system return
|
||||
jg do_single_step # branch to do_sigtrap
|
||||
@ -392,7 +390,7 @@ sysc_tracesys:
|
||||
lghi %r0,NR_syscalls
|
||||
clgr %r0,%r2
|
||||
jnh sysc_tracenogo
|
||||
slag %r7,%r2,2 # *4
|
||||
sllg %r7,%r2,2 # svc number *4
|
||||
lgf %r8,0(%r7,%r10)
|
||||
sysc_tracego:
|
||||
lmg %r3,%r6,SP_R3(%r15)
|
||||
@ -567,8 +565,7 @@ pgm_svcper:
|
||||
# per was called from kernel, must be kprobes
|
||||
#
|
||||
kernel_per:
|
||||
lhi %r0,__LC_PGM_OLD_PSW
|
||||
sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
|
||||
xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
|
||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||
larl %r14,sysc_restore # load adr. of system ret, no work
|
||||
jg do_single_step # branch to do_single_step
|
||||
|
Reference in New Issue
Block a user