diff options
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 66 |
1 files changed, 25 insertions, 41 deletions
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) |