diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-10-30 10:16:49 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-10-30 10:16:43 -0400 |
commit | b6ef5bb3d93efb95ba855a628740375c2280a59e (patch) | |
tree | fc26947a0111c7e71085a81e26f12c815f3f4c09 /arch/s390 | |
parent | ccf45cafb0805978e6f13a672caca0e536e87cad (diff) |
[S390] add TIF_SYSCALL thread flag
Add an explicit TIF_SYSCALL bit that indicates if a task is inside
a system call. The svc_code in the pt_regs structure is now only
valid if TIF_SYSCALL is set. With this definition TIF_RESTART_SVC
can be replaced with TIF_SYSCALL. Overall do_signal is a bit more
readable and it saves a few lines of code.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/syscall.h | 3 | ||||
-rw-r--r-- | arch/s390/include/asm/thread_info.h | 4 | ||||
-rw-r--r-- | arch/s390/kernel/compat_signal.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 66 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 67 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/signal.c | 19 |
7 files changed, 69 insertions, 94 deletions
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h index 614267f60713..b239ff53b189 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h | |||
@@ -26,7 +26,8 @@ extern const unsigned int sys_call_table[]; | |||
26 | static inline long syscall_get_nr(struct task_struct *task, | 26 | static inline long syscall_get_nr(struct task_struct *task, |
27 | struct pt_regs *regs) | 27 | struct pt_regs *regs) |
28 | { | 28 | { |
29 | return regs->svc_code ? (regs->svc_code & 0xffff) : -1; | 29 | return test_tsk_thread_flag(task, TIF_SYSCALL) ? |
30 | (regs->svc_code & 0xffff) : -1; | ||
30 | } | 31 | } |
31 | 32 | ||
32 | static inline void syscall_rollback(struct task_struct *task, | 33 | static inline void syscall_rollback(struct task_struct *task, |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 0c4788eb5a65..a23183423b14 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -85,10 +85,10 @@ static inline struct thread_info *current_thread_info(void) | |||
85 | /* | 85 | /* |
86 | * thread information flags bit numbers | 86 | * thread information flags bit numbers |
87 | */ | 87 | */ |
88 | #define TIF_SYSCALL 0 /* inside a system call */ | ||
88 | #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ | 89 | #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ |
89 | #define TIF_SIGPENDING 2 /* signal pending */ | 90 | #define TIF_SIGPENDING 2 /* signal pending */ |
90 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | 91 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
91 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ | ||
92 | #define TIF_PER_TRAP 6 /* deliver sigtrap on return to user */ | 92 | #define TIF_PER_TRAP 6 /* deliver sigtrap on return to user */ |
93 | #define TIF_MCCK_PENDING 7 /* machine check handling is pending */ | 93 | #define TIF_MCCK_PENDING 7 /* machine check handling is pending */ |
94 | #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ | 94 | #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ |
@@ -104,11 +104,11 @@ static inline struct thread_info *current_thread_info(void) | |||
104 | #define TIF_SINGLE_STEP 20 /* This task is single stepped */ | 104 | #define TIF_SINGLE_STEP 20 /* This task is single stepped */ |
105 | #define TIF_FREEZE 21 /* thread is freezing for suspend */ | 105 | #define TIF_FREEZE 21 /* thread is freezing for suspend */ |
106 | 106 | ||
107 | #define _TIF_SYSCALL (1<<TIF_SYSCALL) | ||
107 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | 108 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) |
108 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | 109 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) |
109 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 110 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
110 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 111 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
111 | #define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC) | ||
112 | #define _TIF_PER_TRAP (1<<TIF_PER_TRAP) | 112 | #define _TIF_PER_TRAP (1<<TIF_PER_TRAP) |
113 | #define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING) | 113 | #define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING) |
114 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 114 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index d7c8e54c32e7..72a1c8d8d212 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -342,7 +342,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) | |||
342 | return err; | 342 | return err; |
343 | 343 | ||
344 | restore_fp_regs(¤t->thread.fp_regs); | 344 | restore_fp_regs(¤t->thread.fp_regs); |
345 | regs->svc_code = 0; /* disable syscall checks */ | 345 | clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */ |
346 | return 0; | 346 | return 0; |
347 | } | 347 | } |
348 | 348 | ||
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index afe3685d30e7..b13157057e02 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -47,11 +47,11 @@ SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE | |||
47 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | 47 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE |
48 | 48 | ||
49 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 49 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
50 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_PER_TRAP ) | 50 | _TIF_MCCK_PENDING | _TIF_PER_TRAP ) |
51 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 51 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
52 | _TIF_MCCK_PENDING) | 52 | _TIF_MCCK_PENDING) |
53 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | 53 | _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ |
54 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) | 54 | _TIF_SYSCALL_TRACEPOINT) |
55 | 55 | ||
56 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 56 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
57 | STACK_SIZE = 1 << STACK_SHIFT | 57 | STACK_SIZE = 1 << STACK_SHIFT |
@@ -227,9 +227,10 @@ ENTRY(system_call) | |||
227 | sysc_saveall: | 227 | sysc_saveall: |
228 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 228 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
229 | CREATE_STACK_FRAME __LC_SAVE_AREA | 229 | CREATE_STACK_FRAME __LC_SAVE_AREA |
230 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
230 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW | 231 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW |
231 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC | 232 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC |
232 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 233 | oi __TI_flags+3(%r12),_TIF_SYSCALL |
233 | sysc_vtime: | 234 | sysc_vtime: |
234 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 235 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
235 | sysc_stime: | 236 | sysc_stime: |
@@ -248,7 +249,7 @@ sysc_do_svc: | |||
248 | sysc_nr_ok: | 249 | sysc_nr_ok: |
249 | sll %r7,2 # svc number *4 | 250 | sll %r7,2 # svc number *4 |
250 | l %r10,BASED(.Lsysc_table) | 251 | l %r10,BASED(.Lsysc_table) |
251 | tm __TI_flags+2(%r12),_TIF_SYSCALL | 252 | tm __TI_flags+2(%r12),_TIF_TRACE >> 8 |
252 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | 253 | mvc SP_ARGS(4,%r15),SP_R7(%r15) |
253 | l %r8,0(%r7,%r10) # get system call addr. | 254 | l %r8,0(%r7,%r10) # get system call addr. |
254 | bnz BASED(sysc_tracesys) | 255 | bnz BASED(sysc_tracesys) |
@@ -258,23 +259,19 @@ sysc_nr_ok: | |||
258 | sysc_return: | 259 | sysc_return: |
259 | LOCKDEP_SYS_EXIT | 260 | LOCKDEP_SYS_EXIT |
260 | sysc_tif: | 261 | sysc_tif: |
262 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
263 | bno BASED(sysc_restore) | ||
261 | tm __TI_flags+3(%r12),_TIF_WORK_SVC | 264 | tm __TI_flags+3(%r12),_TIF_WORK_SVC |
262 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 265 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
266 | ni __TI_flags+3(%r12),255-_TIF_SYSCALL | ||
263 | sysc_restore: | 267 | sysc_restore: |
264 | RESTORE_ALL __LC_RETURN_PSW,1 | 268 | RESTORE_ALL __LC_RETURN_PSW,1 |
265 | sysc_done: | 269 | sysc_done: |
266 | 270 | ||
267 | # | 271 | # |
268 | # There is work to do, but first we need to check if we return to userspace. | ||
269 | # | ||
270 | sysc_work: | ||
271 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
272 | bno BASED(sysc_restore) | ||
273 | |||
274 | # | ||
275 | # One of the work bits is on. Find out which one. | 272 | # One of the work bits is on. Find out which one. |
276 | # | 273 | # |
277 | sysc_work_tif: | 274 | sysc_work: |
278 | tm __TI_flags+3(%r12),_TIF_MCCK_PENDING | 275 | tm __TI_flags+3(%r12),_TIF_MCCK_PENDING |
279 | bo BASED(sysc_mcck_pending) | 276 | bo BASED(sysc_mcck_pending) |
280 | tm __TI_flags+3(%r12),_TIF_NEED_RESCHED | 277 | tm __TI_flags+3(%r12),_TIF_NEED_RESCHED |
@@ -283,8 +280,6 @@ sysc_work_tif: | |||
283 | bo BASED(sysc_sigpending) | 280 | bo BASED(sysc_sigpending) |
284 | tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME | 281 | tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME |
285 | bo BASED(sysc_notify_resume) | 282 | bo BASED(sysc_notify_resume) |
286 | tm __TI_flags+3(%r12),_TIF_RESTART_SVC | ||
287 | bo BASED(sysc_restart) | ||
288 | tm __TI_flags+3(%r12),_TIF_PER_TRAP | 283 | tm __TI_flags+3(%r12),_TIF_PER_TRAP |
289 | bo BASED(sysc_singlestep) | 284 | bo BASED(sysc_singlestep) |
290 | b BASED(sysc_return) # beware of critical section cleanup | 285 | b BASED(sysc_return) # beware of critical section cleanup |
@@ -313,11 +308,14 @@ sysc_sigpending: | |||
313 | la %r2,SP_PTREGS(%r15) # load pt_regs | 308 | la %r2,SP_PTREGS(%r15) # load pt_regs |
314 | l %r1,BASED(.Ldo_signal) | 309 | l %r1,BASED(.Ldo_signal) |
315 | basr %r14,%r1 # call do_signal | 310 | basr %r14,%r1 # call do_signal |
316 | tm __TI_flags+3(%r12),_TIF_RESTART_SVC | 311 | tm __TI_flags+3(%r12),_TIF_SYSCALL |
317 | bo BASED(sysc_restart) | 312 | bno BASED(sysc_return) |
318 | tm __TI_flags+3(%r12),_TIF_PER_TRAP | 313 | lm %r2,%r6,SP_R2(%r15) # load svc arguments |
319 | bo BASED(sysc_singlestep) | 314 | xr %r7,%r7 # svc 0 returns -ENOSYS |
320 | b BASED(sysc_return) | 315 | clc SP_SVC_CODE+2(2,%r15),BASED(.Lnr_syscalls+2) |
316 | bnl BASED(sysc_nr_ok) # invalid svc number -> do svc 0 | ||
317 | icm %r7,3,SP_SVC_CODE+2(%r15)# load new svc number | ||
318 | b BASED(sysc_nr_ok) # restart svc | ||
321 | 319 | ||
322 | # | 320 | # |
323 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume | 321 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume |
@@ -328,25 +326,11 @@ sysc_notify_resume: | |||
328 | la %r14,BASED(sysc_return) | 326 | la %r14,BASED(sysc_return) |
329 | br %r1 # call do_notify_resume | 327 | br %r1 # call do_notify_resume |
330 | 328 | ||
331 | |||
332 | # | ||
333 | # _TIF_RESTART_SVC is set, set up registers and restart svc | ||
334 | # | ||
335 | sysc_restart: | ||
336 | ni __TI_flags+3(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC | ||
337 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | ||
338 | xr %r7,%r7 # svc 0 returns -ENOSYS | ||
339 | clc SP_SVC_CODE+2(%r15),BASED(.Lnr_syscalls+2) | ||
340 | bnl BASED(sysc_nr_ok) # invalid svc number -> do svc 0 | ||
341 | icm %r7,3,SP_SVC_CODE+2(%r15)# load new svc number | ||
342 | b BASED(sysc_nr_ok) # restart svc | ||
343 | |||
344 | # | 329 | # |
345 | # _TIF_PER_TRAP is set, call do_per_trap | 330 | # _TIF_PER_TRAP is set, call do_per_trap |
346 | # | 331 | # |
347 | sysc_singlestep: | 332 | sysc_singlestep: |
348 | ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP | 333 | ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) |
349 | xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) # clear svc code | ||
350 | la %r2,SP_PTREGS(%r15) # address of register-save area | 334 | la %r2,SP_PTREGS(%r15) # address of register-save area |
351 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 335 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
352 | la %r14,BASED(sysc_return) # load adr. of system return | 336 | la %r14,BASED(sysc_return) # load adr. of system return |
@@ -376,7 +360,7 @@ sysc_tracego: | |||
376 | basr %r14,%r8 # call sys_xxx | 360 | basr %r14,%r8 # call sys_xxx |
377 | st %r2,SP_R2(%r15) # store return value | 361 | st %r2,SP_R2(%r15) # store return value |
378 | sysc_tracenogo: | 362 | sysc_tracenogo: |
379 | tm __TI_flags+2(%r12),_TIF_SYSCALL | 363 | tm __TI_flags+2(%r12),_TIF_TRACE >> 8 |
380 | bz BASED(sysc_return) | 364 | bz BASED(sysc_return) |
381 | l %r1,BASED(.Ltrace_exit) | 365 | l %r1,BASED(.Ltrace_exit) |
382 | la %r2,SP_PTREGS(%r15) # load pt_regs | 366 | la %r2,SP_PTREGS(%r15) # load pt_regs |
@@ -454,7 +438,6 @@ ENTRY(pgm_check_handler) | |||
454 | bnz BASED(pgm_per) # got per exception -> special case | 438 | bnz BASED(pgm_per) # got per exception -> special case |
455 | SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 439 | SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
456 | CREATE_STACK_FRAME __LC_SAVE_AREA | 440 | CREATE_STACK_FRAME __LC_SAVE_AREA |
457 | xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) | ||
458 | mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW | 441 | mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW |
459 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 442 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
460 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 443 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -530,9 +513,10 @@ pgm_exit2: | |||
530 | pgm_svcper: | 513 | pgm_svcper: |
531 | SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 514 | SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
532 | CREATE_STACK_FRAME __LC_SAVE_AREA | 515 | CREATE_STACK_FRAME __LC_SAVE_AREA |
516 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
533 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW | 517 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW |
534 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC | 518 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC |
535 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 519 | oi __TI_flags+3(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP) |
536 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 520 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
537 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 521 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
538 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 522 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
@@ -540,7 +524,6 @@ pgm_svcper: | |||
540 | mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE | 524 | mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE |
541 | mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS | 525 | mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS |
542 | mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID | 526 | mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID |
543 | oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP | ||
544 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 527 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
545 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | 528 | lm %r2,%r6,SP_R2(%r15) # load svc arguments |
546 | b BASED(sysc_do_svc) | 529 | b BASED(sysc_do_svc) |
@@ -550,7 +533,6 @@ pgm_svcper: | |||
550 | # | 533 | # |
551 | kernel_per: | 534 | kernel_per: |
552 | REENABLE_IRQS | 535 | REENABLE_IRQS |
553 | xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) | ||
554 | la %r2,SP_PTREGS(%r15) # address of register-save area | 536 | la %r2,SP_PTREGS(%r15) # address of register-save area |
555 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 537 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
556 | basr %r14,%r1 # branch to do_single_step | 538 | basr %r14,%r1 # branch to do_single_step |
@@ -965,9 +947,11 @@ cleanup_system_call: | |||
965 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 947 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
966 | st %r15,12(%r12) | 948 | st %r15,12(%r12) |
967 | CREATE_STACK_FRAME __LC_SAVE_AREA | 949 | CREATE_STACK_FRAME __LC_SAVE_AREA |
950 | mvc 0(4,%r12),__LC_THREAD_INFO | ||
951 | l %r12,__LC_THREAD_INFO | ||
968 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW | 952 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW |
969 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC | 953 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC |
970 | mvc 0(4,%r12),__LC_THREAD_INFO | 954 | oi __TI_flags+3(%r12),_TIF_SYSCALL |
971 | cleanup_vtime: | 955 | cleanup_vtime: |
972 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) | 956 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) |
973 | bhe BASED(cleanup_stime) | 957 | bhe BASED(cleanup_stime) |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 7ff07d3a29c1..e34907560c23 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -50,11 +50,11 @@ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | |||
50 | STACK_SIZE = 1 << STACK_SHIFT | 50 | STACK_SIZE = 1 << STACK_SHIFT |
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 | \ |
53 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_PER_TRAP ) | 53 | _TIF_MCCK_PENDING | _TIF_PER_TRAP ) |
54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
55 | _TIF_MCCK_PENDING) | 55 | _TIF_MCCK_PENDING) |
56 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | 56 | _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ |
57 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) | 57 | _TIF_SYSCALL_TRACEPOINT) |
58 | _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | 58 | _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) |
59 | 59 | ||
60 | #define BASED(name) name-system_call(%r13) | 60 | #define BASED(name) name-system_call(%r13) |
@@ -248,9 +248,10 @@ ENTRY(system_call) | |||
248 | sysc_saveall: | 248 | sysc_saveall: |
249 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 249 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
250 | CREATE_STACK_FRAME __LC_SAVE_AREA | 250 | CREATE_STACK_FRAME __LC_SAVE_AREA |
251 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
251 | mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW | 252 | mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW |
252 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC | 253 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC |
253 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 254 | oi __TI_flags+7(%r12),_TIF_SYSCALL |
254 | sysc_vtime: | 255 | sysc_vtime: |
255 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 256 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
256 | sysc_stime: | 257 | sysc_stime: |
@@ -276,7 +277,7 @@ sysc_nr_ok: | |||
276 | larl %r10,sys_call_table_emu # use 31 bit emulation system calls | 277 | larl %r10,sys_call_table_emu # use 31 bit emulation system calls |
277 | sysc_noemu: | 278 | sysc_noemu: |
278 | #endif | 279 | #endif |
279 | tm __TI_flags+6(%r12),_TIF_SYSCALL | 280 | tm __TI_flags+6(%r12),_TIF_TRACE >> 8 |
280 | mvc SP_ARGS(8,%r15),SP_R7(%r15) | 281 | mvc SP_ARGS(8,%r15),SP_R7(%r15) |
281 | lgf %r8,0(%r7,%r10) # load address of system call routine | 282 | lgf %r8,0(%r7,%r10) # load address of system call routine |
282 | jnz sysc_tracesys | 283 | jnz sysc_tracesys |
@@ -286,23 +287,19 @@ sysc_noemu: | |||
286 | sysc_return: | 287 | sysc_return: |
287 | LOCKDEP_SYS_EXIT | 288 | LOCKDEP_SYS_EXIT |
288 | sysc_tif: | 289 | sysc_tif: |
290 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
291 | jno sysc_restore | ||
289 | tm __TI_flags+7(%r12),_TIF_WORK_SVC | 292 | tm __TI_flags+7(%r12),_TIF_WORK_SVC |
290 | jnz sysc_work # there is work to do (signals etc.) | 293 | jnz sysc_work # there is work to do (signals etc.) |
294 | ni __TI_flags+7(%r12),255-_TIF_SYSCALL | ||
291 | sysc_restore: | 295 | sysc_restore: |
292 | RESTORE_ALL __LC_RETURN_PSW,1 | 296 | RESTORE_ALL __LC_RETURN_PSW,1 |
293 | sysc_done: | 297 | sysc_done: |
294 | 298 | ||
295 | # | 299 | # |
296 | # There is work to do, but first we need to check if we return to userspace. | ||
297 | # | ||
298 | sysc_work: | ||
299 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
300 | jno sysc_restore | ||
301 | |||
302 | # | ||
303 | # One of the work bits is on. Find out which one. | 300 | # One of the work bits is on. Find out which one. |
304 | # | 301 | # |
305 | sysc_work_tif: | 302 | sysc_work: |
306 | tm __TI_flags+7(%r12),_TIF_MCCK_PENDING | 303 | tm __TI_flags+7(%r12),_TIF_MCCK_PENDING |
307 | jo sysc_mcck_pending | 304 | jo sysc_mcck_pending |
308 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED | 305 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED |
@@ -311,8 +308,6 @@ sysc_work_tif: | |||
311 | jo sysc_sigpending | 308 | jo sysc_sigpending |
312 | tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME | 309 | tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME |
313 | jo sysc_notify_resume | 310 | jo sysc_notify_resume |
314 | tm __TI_flags+7(%r12),_TIF_RESTART_SVC | ||
315 | jo sysc_restart | ||
316 | tm __TI_flags+7(%r12),_TIF_PER_TRAP | 311 | tm __TI_flags+7(%r12),_TIF_PER_TRAP |
317 | jo sysc_singlestep | 312 | jo sysc_singlestep |
318 | j sysc_return # beware of critical section cleanup | 313 | j sysc_return # beware of critical section cleanup |
@@ -338,11 +333,15 @@ sysc_sigpending: | |||
338 | ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP | 333 | ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP |
339 | la %r2,SP_PTREGS(%r15) # load pt_regs | 334 | la %r2,SP_PTREGS(%r15) # load pt_regs |
340 | brasl %r14,do_signal # call do_signal | 335 | brasl %r14,do_signal # call do_signal |
341 | tm __TI_flags+7(%r12),_TIF_RESTART_SVC | 336 | tm __TI_flags+7(%r12),_TIF_SYSCALL |
342 | jo sysc_restart | 337 | jno sysc_return |
343 | tm __TI_flags+7(%r12),_TIF_PER_TRAP | 338 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments |
344 | jo sysc_singlestep | 339 | lghi %r7,0 # svc 0 returns -ENOSYS |
345 | j sysc_return | 340 | lh %r1,SP_SVC_CODE+2(%r15) # load new svc number |
341 | cghi %r1,NR_syscalls | ||
342 | jnl sysc_nr_ok # invalid svc number -> do svc 0 | ||
343 | slag %r7,%r1,2 | ||
344 | j sysc_nr_ok # restart svc | ||
346 | 345 | ||
347 | # | 346 | # |
348 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume | 347 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume |
@@ -353,24 +352,10 @@ sysc_notify_resume: | |||
353 | jg do_notify_resume # call do_notify_resume | 352 | jg do_notify_resume # call do_notify_resume |
354 | 353 | ||
355 | # | 354 | # |
356 | # _TIF_RESTART_SVC is set, set up registers and restart svc | ||
357 | # | ||
358 | sysc_restart: | ||
359 | ni __TI_flags+7(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC | ||
360 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments | ||
361 | lghi %r7,0 # svc 0 returns -ENOSYS | ||
362 | lh %r1,SP_SVC_CODE+2(%r15) # load new svc number | ||
363 | cghi %r1,NR_syscalls | ||
364 | jnl sysc_nr_ok # invalid svc number -> do svc 0 | ||
365 | slag %r7,%r1,2 | ||
366 | j sysc_nr_ok # restart svc | ||
367 | |||
368 | # | ||
369 | # _TIF_PER_TRAP is set, call do_per_trap | 355 | # _TIF_PER_TRAP is set, call do_per_trap |
370 | # | 356 | # |
371 | sysc_singlestep: | 357 | sysc_singlestep: |
372 | ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP | 358 | ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) |
373 | xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) # clear svc code | ||
374 | la %r2,SP_PTREGS(%r15) # address of register-save area | 359 | la %r2,SP_PTREGS(%r15) # address of register-save area |
375 | larl %r14,sysc_return # load adr. of system return | 360 | larl %r14,sysc_return # load adr. of system return |
376 | jg do_per_trap | 361 | jg do_per_trap |
@@ -397,7 +382,7 @@ sysc_tracego: | |||
397 | basr %r14,%r8 # call sys_xxx | 382 | basr %r14,%r8 # call sys_xxx |
398 | stg %r2,SP_R2(%r15) # store return value | 383 | stg %r2,SP_R2(%r15) # store return value |
399 | sysc_tracenogo: | 384 | sysc_tracenogo: |
400 | tm __TI_flags+6(%r12),_TIF_SYSCALL | 385 | tm __TI_flags+6(%r12),_TIF_TRACE >> 8 |
401 | jz sysc_return | 386 | jz sysc_return |
402 | la %r2,SP_PTREGS(%r15) # load pt_regs | 387 | la %r2,SP_PTREGS(%r15) # load pt_regs |
403 | larl %r14,sysc_return # return point is sysc_return | 388 | larl %r14,sysc_return # return point is sysc_return |
@@ -470,7 +455,6 @@ ENTRY(pgm_check_handler) | |||
470 | jnz pgm_per # got per exception -> special case | 455 | jnz pgm_per # got per exception -> special case |
471 | SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 456 | SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
472 | CREATE_STACK_FRAME __LC_SAVE_AREA | 457 | CREATE_STACK_FRAME __LC_SAVE_AREA |
473 | xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) | ||
474 | mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW | 458 | mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW |
475 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 459 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
476 | HANDLE_SIE_INTERCEPT | 460 | HANDLE_SIE_INTERCEPT |
@@ -550,9 +534,10 @@ pgm_exit2: | |||
550 | pgm_svcper: | 534 | pgm_svcper: |
551 | SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 535 | SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
552 | CREATE_STACK_FRAME __LC_SAVE_AREA | 536 | CREATE_STACK_FRAME __LC_SAVE_AREA |
537 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
553 | mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW | 538 | mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW |
554 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC | 539 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC |
555 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 540 | oi __TI_flags+7(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP) |
556 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 541 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
557 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 542 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
558 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 543 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
@@ -561,7 +546,6 @@ pgm_svcper: | |||
561 | mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE | 546 | mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE |
562 | mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS | 547 | mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS |
563 | mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID | 548 | mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID |
564 | oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP | ||
565 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 549 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
566 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments | 550 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments |
567 | j sysc_do_svc | 551 | j sysc_do_svc |
@@ -571,7 +555,6 @@ pgm_svcper: | |||
571 | # | 555 | # |
572 | kernel_per: | 556 | kernel_per: |
573 | REENABLE_IRQS | 557 | REENABLE_IRQS |
574 | xc SP_SVC_CODE(4,%r15),SP_SVC_CODE(%r15) # clear svc number | ||
575 | la %r2,SP_PTREGS(%r15) # address of register-save area | 558 | la %r2,SP_PTREGS(%r15) # address of register-save area |
576 | brasl %r14,do_per_trap | 559 | brasl %r14,do_per_trap |
577 | j pgm_exit | 560 | j pgm_exit |
@@ -972,9 +955,11 @@ cleanup_system_call: | |||
972 | stg %r15,32(%r12) | 955 | stg %r15,32(%r12) |
973 | stg %r11,0(%r12) | 956 | stg %r11,0(%r12) |
974 | CREATE_STACK_FRAME __LC_SAVE_AREA | 957 | CREATE_STACK_FRAME __LC_SAVE_AREA |
958 | mvc 8(8,%r12),__LC_THREAD_INFO | ||
959 | lg %r12,__LC_THREAD_INFO | ||
975 | mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW | 960 | mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW |
976 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC | 961 | mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC |
977 | mvc 8(8,%r12),__LC_THREAD_INFO | 962 | oi __TI_flags+7(%r12),_TIF_SYSCALL |
978 | cleanup_vtime: | 963 | cleanup_vtime: |
979 | clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) | 964 | clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) |
980 | jhe cleanup_stime | 965 | jhe cleanup_stime |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index bae1cc49fe96..3519c99ae0c0 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -750,7 +750,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
750 | * debugger stored an invalid system call number. Skip | 750 | * debugger stored an invalid system call number. Skip |
751 | * the system call and the system call restart handling. | 751 | * the system call and the system call restart handling. |
752 | */ | 752 | */ |
753 | regs->svc_code = 0; | 753 | clear_thread_flag(TIF_SYSCALL); |
754 | ret = -1; | 754 | ret = -1; |
755 | } | 755 | } |
756 | 756 | ||
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 058e372bada1..0e905cb7604a 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -157,7 +157,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) | |||
157 | current->thread.fp_regs.fpc &= FPC_VALID_MASK; | 157 | current->thread.fp_regs.fpc &= FPC_VALID_MASK; |
158 | 158 | ||
159 | restore_fp_regs(¤t->thread.fp_regs); | 159 | restore_fp_regs(¤t->thread.fp_regs); |
160 | regs->svc_code = 0; /* disable syscall checks */ | 160 | clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */ |
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
@@ -426,13 +426,14 @@ void do_signal(struct pt_regs *regs) | |||
426 | * the debugger may change all our registers, including the system | 426 | * the debugger may change all our registers, including the system |
427 | * call information. | 427 | * call information. |
428 | */ | 428 | */ |
429 | current_thread_info()->system_call = regs->svc_code; | 429 | current_thread_info()->system_call = |
430 | test_thread_flag(TIF_SYSCALL) ? regs->svc_code : 0; | ||
430 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 431 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
431 | regs->svc_code = current_thread_info()->system_call; | ||
432 | 432 | ||
433 | if (signr > 0) { | 433 | if (signr > 0) { |
434 | /* Whee! Actually deliver the signal. */ | 434 | /* Whee! Actually deliver the signal. */ |
435 | if (regs->svc_code > 0) { | 435 | if (current_thread_info()->system_call) { |
436 | regs->svc_code = current_thread_info()->system_call; | ||
436 | /* Check for system call restarting. */ | 437 | /* Check for system call restarting. */ |
437 | switch (regs->gprs[2]) { | 438 | switch (regs->gprs[2]) { |
438 | case -ERESTART_RESTARTBLOCK: | 439 | case -ERESTART_RESTARTBLOCK: |
@@ -453,7 +454,7 @@ void do_signal(struct pt_regs *regs) | |||
453 | break; | 454 | break; |
454 | } | 455 | } |
455 | /* No longer in a system call */ | 456 | /* No longer in a system call */ |
456 | regs->svc_code = 0; | 457 | clear_thread_flag(TIF_SYSCALL); |
457 | } | 458 | } |
458 | 459 | ||
459 | if ((is_compat_task() ? | 460 | if ((is_compat_task() ? |
@@ -478,7 +479,8 @@ void do_signal(struct pt_regs *regs) | |||
478 | } | 479 | } |
479 | 480 | ||
480 | /* No handlers present - check for system call restart */ | 481 | /* No handlers present - check for system call restart */ |
481 | if (regs->svc_code > 0) { | 482 | if (current_thread_info()->system_call) { |
483 | regs->svc_code = current_thread_info()->system_call; | ||
482 | switch (regs->gprs[2]) { | 484 | switch (regs->gprs[2]) { |
483 | case -ERESTART_RESTARTBLOCK: | 485 | case -ERESTART_RESTARTBLOCK: |
484 | /* Restart with sys_restart_syscall */ | 486 | /* Restart with sys_restart_syscall */ |
@@ -489,7 +491,10 @@ void do_signal(struct pt_regs *regs) | |||
489 | case -ERESTARTNOINTR: | 491 | case -ERESTARTNOINTR: |
490 | /* Restart system call with magic TIF bit. */ | 492 | /* Restart system call with magic TIF bit. */ |
491 | regs->gprs[2] = regs->orig_gpr2; | 493 | regs->gprs[2] = regs->orig_gpr2; |
492 | set_thread_flag(TIF_RESTART_SVC); | 494 | set_thread_flag(TIF_SYSCALL); |
495 | break; | ||
496 | default: | ||
497 | clear_thread_flag(TIF_SYSCALL); | ||
493 | break; | 498 | break; |
494 | } | 499 | } |
495 | } | 500 | } |