diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-11-27 05:05:55 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-11-27 05:06:56 -0500 |
commit | 59da21398e680e8100625d689c8bebee6a139e93 (patch) | |
tree | 7d93f87d2942dac06367af8b3a269e9f6d557b29 | |
parent | ed313489badef16d700f5a3be50e8fd8f8294bc8 (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>
-rw-r--r-- | arch/s390/include/asm/ptrace.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/syscall.h | 28 | ||||
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/compat_signal.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 21 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 23 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/signal.c | 6 |
8 files changed, 44 insertions, 42 deletions
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index a7226f8143fb..fb0ca4796d3b 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h | |||
@@ -321,8 +321,8 @@ struct pt_regs | |||
321 | psw_t psw; | 321 | psw_t psw; |
322 | unsigned long gprs[NUM_GPRS]; | 322 | unsigned long gprs[NUM_GPRS]; |
323 | unsigned long orig_gpr2; | 323 | unsigned long orig_gpr2; |
324 | unsigned short svcnr; | ||
324 | unsigned short ilc; | 325 | unsigned short ilc; |
325 | unsigned short trap; | ||
326 | }; | 326 | }; |
327 | #endif | 327 | #endif |
328 | 328 | ||
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h index 6e623971fbb9..2429b87eb28d 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h | |||
@@ -17,9 +17,7 @@ | |||
17 | static inline long syscall_get_nr(struct task_struct *task, | 17 | static inline long syscall_get_nr(struct task_struct *task, |
18 | struct pt_regs *regs) | 18 | struct pt_regs *regs) |
19 | { | 19 | { |
20 | if (regs->trap != __LC_SVC_OLD_PSW) | 20 | return regs->svcnr ? regs->svcnr : -1; |
21 | return -1; | ||
22 | return regs->gprs[2]; | ||
23 | } | 21 | } |
24 | 22 | ||
25 | static inline void syscall_rollback(struct task_struct *task, | 23 | static inline void syscall_rollback(struct task_struct *task, |
@@ -52,18 +50,20 @@ static inline void syscall_get_arguments(struct task_struct *task, | |||
52 | unsigned int i, unsigned int n, | 50 | unsigned int i, unsigned int n, |
53 | unsigned long *args) | 51 | unsigned long *args) |
54 | { | 52 | { |
53 | unsigned long mask = -1UL; | ||
54 | |||
55 | BUG_ON(i + n > 6); | 55 | BUG_ON(i + n > 6); |
56 | #ifdef CONFIG_COMPAT | 56 | #ifdef CONFIG_COMPAT |
57 | if (test_tsk_thread_flag(task, TIF_31BIT)) { | 57 | if (test_tsk_thread_flag(task, TIF_31BIT)) |
58 | if (i + n == 6) | 58 | mask = 0xffffffff; |
59 | args[--n] = (u32) regs->args[0]; | ||
60 | while (n-- > 0) | ||
61 | args[n] = (u32) regs->gprs[2 + i + n]; | ||
62 | } | ||
63 | #endif | 59 | #endif |
64 | if (i + n == 6) | 60 | if (i + n == 6) |
65 | args[--n] = regs->args[0]; | 61 | args[--n] = regs->args[0] & mask; |
66 | memcpy(args, ®s->gprs[2 + i], n * sizeof(args[0])); | 62 | while (n-- > 0) |
63 | if (i + n > 0) | ||
64 | args[n] = regs->gprs[2 + i + n] & mask; | ||
65 | if (i == 0) | ||
66 | args[0] = regs->orig_gpr2 & mask; | ||
67 | } | 67 | } |
68 | 68 | ||
69 | static inline void syscall_set_arguments(struct task_struct *task, | 69 | static inline void syscall_set_arguments(struct task_struct *task, |
@@ -74,7 +74,11 @@ static inline void syscall_set_arguments(struct task_struct *task, | |||
74 | BUG_ON(i + n > 6); | 74 | BUG_ON(i + n > 6); |
75 | if (i + n == 6) | 75 | if (i + n == 6) |
76 | regs->args[0] = args[--n]; | 76 | regs->args[0] = args[--n]; |
77 | memcpy(®s->gprs[2 + i], args, n * sizeof(args[0])); | 77 | while (n-- > 0) |
78 | if (i + n > 0) | ||
79 | regs->gprs[2 + i + n] = args[n]; | ||
80 | if (i == 0) | ||
81 | regs->orig_gpr2 = args[0]; | ||
78 | } | 82 | } |
79 | 83 | ||
80 | #endif /* _ASM_SYSCALL_H */ | 84 | #endif /* _ASM_SYSCALL_H */ |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index fa28ecae636b..3d144e6020c6 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -32,7 +32,7 @@ int main(void) | |||
32 | DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs)); | 32 | DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs)); |
33 | DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2)); | 33 | DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2)); |
34 | DEFINE(__PT_ILC, offsetof(struct pt_regs, ilc)); | 34 | DEFINE(__PT_ILC, offsetof(struct pt_regs, ilc)); |
35 | DEFINE(__PT_TRAP, offsetof(struct pt_regs, trap)); | 35 | DEFINE(__PT_SVCNR, offsetof(struct pt_regs, svcnr)); |
36 | DEFINE(__PT_SIZE, sizeof(struct pt_regs)); | 36 | DEFINE(__PT_SIZE, sizeof(struct pt_regs)); |
37 | BLANK(); | 37 | BLANK(); |
38 | DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain)); | 38 | DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain)); |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index c7f02e777af2..b537cb0e9b55 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -340,7 +340,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) | |||
340 | return err; | 340 | return err; |
341 | 341 | ||
342 | restore_fp_regs(¤t->thread.fp_regs); | 342 | restore_fp_regs(¤t->thread.fp_regs); |
343 | regs->trap = -1; /* disable syscall checks */ | 343 | regs->svcnr = 0; /* disable syscall checks */ |
344 | return 0; | 344 | return 0; |
345 | } | 345 | } |
346 | 346 | ||
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 | |||
46 | SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 | 46 | SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 |
47 | SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 | 47 | SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 |
48 | SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC | 48 | SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC |
49 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP | 49 | SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR |
50 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | 50 | SP_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 |
265 | sysc_do_svc: | 264 | sysc_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 | ||
274 | sysc_nr_ok: | 272 | sysc_nr_ok: |
275 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | 273 | mvc SP_ARGS(4,%r15),SP_R7(%r15) |
276 | sysc_do_restart: | 274 | sysc_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: | |||
376 | sysc_restart: | 376 | sysc_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 | # |
387 | sysc_singlestep: | 386 | sysc_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) |
412 | sysc_tracego: | 412 | sysc_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 | # |
588 | kernel_per: | 588 | kernel_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 |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 41aca06682aa..89c121ae6339 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -46,7 +46,7 @@ SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112 | |||
46 | SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120 | 46 | SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120 |
47 | SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 | 47 | SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 |
48 | SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC | 48 | SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC |
49 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP | 49 | SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR |
50 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | 50 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE |
51 | 51 | ||
52 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 52 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
@@ -171,11 +171,10 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | |||
171 | .macro CREATE_STACK_FRAME psworg,savearea | 171 | .macro CREATE_STACK_FRAME psworg,savearea |
172 | aghi %r15,-SP_SIZE # make room for registers & psw | 172 | aghi %r15,-SP_SIZE # make room for registers & psw |
173 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack | 173 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack |
174 | la %r12,\psworg | ||
175 | stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 | 174 | stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 |
176 | icm %r12,12,__LC_SVC_ILC | 175 | icm %r12,3,__LC_SVC_ILC |
177 | stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack | 176 | stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack |
178 | st %r12,SP_ILC(%r15) | 177 | st %r12,SP_SVCNR(%r15) |
179 | mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack | 178 | mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack |
180 | la %r12,0 | 179 | la %r12,0 |
181 | stg %r12,__SF_BACKCHAIN(%r15) | 180 | stg %r12,__SF_BACKCHAIN(%r15) |
@@ -250,16 +249,17 @@ sysc_update: | |||
250 | #endif | 249 | #endif |
251 | sysc_do_svc: | 250 | sysc_do_svc: |
252 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 251 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
253 | slag %r7,%r7,2 # *4 and test for svc 0 | 252 | ltgr %r7,%r7 # test for svc 0 |
254 | jnz sysc_nr_ok | 253 | jnz sysc_nr_ok |
255 | # svc 0: system call number in %r1 | 254 | # svc 0: system call number in %r1 |
256 | cl %r1,BASED(.Lnr_syscalls) | 255 | cl %r1,BASED(.Lnr_syscalls) |
257 | jnl sysc_nr_ok | 256 | jnl sysc_nr_ok |
258 | lgfr %r7,%r1 # clear high word in r1 | 257 | lgfr %r7,%r1 # clear high word in r1 |
259 | slag %r7,%r7,2 # svc 0: system call number in %r1 | ||
260 | sysc_nr_ok: | 258 | sysc_nr_ok: |
261 | mvc SP_ARGS(8,%r15),SP_R7(%r15) | 259 | mvc SP_ARGS(8,%r15),SP_R7(%r15) |
262 | sysc_do_restart: | 260 | sysc_do_restart: |
261 | sth %r7,SP_SVCNR(%r15) | ||
262 | sllg %r7,%r7,2 # svc number * 4 | ||
263 | larl %r10,sys_call_table | 263 | larl %r10,sys_call_table |
264 | #ifdef CONFIG_COMPAT | 264 | #ifdef CONFIG_COMPAT |
265 | tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ? | 265 | tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ? |
@@ -363,7 +363,6 @@ sysc_notify_resume: | |||
363 | sysc_restart: | 363 | sysc_restart: |
364 | ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC | 364 | ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC |
365 | lg %r7,SP_R2(%r15) # load new svc number | 365 | lg %r7,SP_R2(%r15) # load new svc number |
366 | slag %r7,%r7,2 # *4 | ||
367 | mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument | 366 | mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument |
368 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments | 367 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments |
369 | j sysc_do_restart # restart svc | 368 | j sysc_do_restart # restart svc |
@@ -372,9 +371,8 @@ sysc_restart: | |||
372 | # _TIF_SINGLE_STEP is set, call do_single_step | 371 | # _TIF_SINGLE_STEP is set, call do_single_step |
373 | # | 372 | # |
374 | sysc_singlestep: | 373 | sysc_singlestep: |
375 | ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP | 374 | ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP |
376 | lhi %r0,__LC_PGM_OLD_PSW | 375 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number |
377 | sth %r0,SP_TRAP(%r15) # set trap indication to pgm check | ||
378 | la %r2,SP_PTREGS(%r15) # address of register-save area | 376 | la %r2,SP_PTREGS(%r15) # address of register-save area |
379 | larl %r14,sysc_return # load adr. of system return | 377 | larl %r14,sysc_return # load adr. of system return |
380 | jg do_single_step # branch to do_sigtrap | 378 | jg do_single_step # branch to do_sigtrap |
@@ -392,7 +390,7 @@ sysc_tracesys: | |||
392 | lghi %r0,NR_syscalls | 390 | lghi %r0,NR_syscalls |
393 | clgr %r0,%r2 | 391 | clgr %r0,%r2 |
394 | jnh sysc_tracenogo | 392 | jnh sysc_tracenogo |
395 | slag %r7,%r2,2 # *4 | 393 | sllg %r7,%r2,2 # svc number *4 |
396 | lgf %r8,0(%r7,%r10) | 394 | lgf %r8,0(%r7,%r10) |
397 | sysc_tracego: | 395 | sysc_tracego: |
398 | lmg %r3,%r6,SP_R3(%r15) | 396 | lmg %r3,%r6,SP_R3(%r15) |
@@ -567,8 +565,7 @@ pgm_svcper: | |||
567 | # per was called from kernel, must be kprobes | 565 | # per was called from kernel, must be kprobes |
568 | # | 566 | # |
569 | kernel_per: | 567 | kernel_per: |
570 | lhi %r0,__LC_PGM_OLD_PSW | 568 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number |
571 | sth %r0,SP_TRAP(%r15) # set trap indication to pgm check | ||
572 | la %r2,SP_PTREGS(%r15) # address of register-save area | 569 | la %r2,SP_PTREGS(%r15) # address of register-save area |
573 | larl %r14,sysc_restore # load adr. of system ret, no work | 570 | larl %r14,sysc_restore # load adr. of system ret, no work |
574 | jg do_single_step # branch to do_single_step | 571 | jg do_single_step # branch to do_single_step |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 1f31be1ecc4b..38ff2bce1203 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -657,7 +657,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
657 | * debugger stored an invalid system call number. Skip | 657 | * debugger stored an invalid system call number. Skip |
658 | * the system call and the system call restart handling. | 658 | * the system call and the system call restart handling. |
659 | */ | 659 | */ |
660 | regs->trap = -1; | 660 | regs->svcnr = 0; |
661 | ret = -1; | 661 | ret = -1; |
662 | } | 662 | } |
663 | 663 | ||
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 4f7fc3059a8e..8e6812a22670 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -160,7 +160,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) | |||
160 | current->thread.fp_regs.fpc &= FPC_VALID_MASK; | 160 | current->thread.fp_regs.fpc &= FPC_VALID_MASK; |
161 | 161 | ||
162 | restore_fp_regs(¤t->thread.fp_regs); | 162 | restore_fp_regs(¤t->thread.fp_regs); |
163 | regs->trap = -1; /* disable syscall checks */ | 163 | regs->svcnr = 0; /* disable syscall checks */ |
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
@@ -445,7 +445,7 @@ void do_signal(struct pt_regs *regs) | |||
445 | oldset = ¤t->blocked; | 445 | oldset = ¤t->blocked; |
446 | 446 | ||
447 | /* Are we from a system call? */ | 447 | /* Are we from a system call? */ |
448 | if (regs->trap == __LC_SVC_OLD_PSW) { | 448 | if (regs->svcnr) { |
449 | continue_addr = regs->psw.addr; | 449 | continue_addr = regs->psw.addr; |
450 | restart_addr = continue_addr - regs->ilc; | 450 | restart_addr = continue_addr - regs->ilc; |
451 | retval = regs->gprs[2]; | 451 | retval = regs->gprs[2]; |
@@ -462,7 +462,7 @@ void do_signal(struct pt_regs *regs) | |||
462 | case -ERESTART_RESTARTBLOCK: | 462 | case -ERESTART_RESTARTBLOCK: |
463 | regs->gprs[2] = -EINTR; | 463 | regs->gprs[2] = -EINTR; |
464 | } | 464 | } |
465 | regs->trap = -1; /* Don't deal with this again. */ | 465 | regs->svcnr = 0; /* Don't deal with this again. */ |
466 | } | 466 | } |
467 | 467 | ||
468 | /* Get signal to deliver. When running under ptrace, at this point | 468 | /* Get signal to deliver. When running under ptrace, at this point |