diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2010-05-17 04:00:02 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-05-17 04:00:15 -0400 |
commit | 6a2df3a87276cdc08fd87070d09ea18d1fb9d622 (patch) | |
tree | 384b646d0a826ab5c2bafa63e9bea4a057815fe2 /arch/s390/kernel | |
parent | 43d399d2ab7e96cb8d952d0ba4e9131587b7c8b9 (diff) |
[S390] improve irq tracing code in entry[64].S
The system call path in entry[64].S is run with interrupts enabled.
Remove the irq tracing check from the system call exit code. If a
program check interrupted a context enabled for interrupts do a
call to trace_irq_off_caller in the program check handler before
branching to the system call exit code.
Restructure the system call and io interrupt return code to avoid
avoid the lpsw[e] to disable machine checks.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/entry.S | 205 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 197 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 4 |
3 files changed, 183 insertions, 223 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index ffebfb64b913..07d849995dac 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -73,21 +73,24 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
73 | basr %r14,%r1 | 73 | basr %r14,%r1 |
74 | .endm | 74 | .endm |
75 | 75 | ||
76 | .macro TRACE_IRQS_CHECK | 76 | .macro TRACE_IRQS_CHECK_ON |
77 | basr %r2,%r0 | ||
78 | tm SP_PSW(%r15),0x03 # irqs enabled? | 77 | tm SP_PSW(%r15),0x03 # irqs enabled? |
79 | jz 0f | 78 | bz BASED(0f) |
80 | l %r1,BASED(.Ltrace_irq_on_caller) | 79 | TRACE_IRQS_ON |
81 | basr %r14,%r1 | 80 | 0: |
82 | j 1f | 81 | .endm |
83 | 0: l %r1,BASED(.Ltrace_irq_off_caller) | 82 | |
84 | basr %r14,%r1 | 83 | .macro TRACE_IRQS_CHECK_OFF |
85 | 1: | 84 | tm SP_PSW(%r15),0x03 # irqs enabled? |
85 | bz BASED(0f) | ||
86 | TRACE_IRQS_OFF | ||
87 | 0: | ||
86 | .endm | 88 | .endm |
87 | #else | 89 | #else |
88 | #define TRACE_IRQS_ON | 90 | #define TRACE_IRQS_ON |
89 | #define TRACE_IRQS_OFF | 91 | #define TRACE_IRQS_OFF |
90 | #define TRACE_IRQS_CHECK | 92 | #define TRACE_IRQS_CHECK_ON |
93 | #define TRACE_IRQS_CHECK_OFF | ||
91 | #endif | 94 | #endif |
92 | 95 | ||
93 | #ifdef CONFIG_LOCKDEP | 96 | #ifdef CONFIG_LOCKDEP |
@@ -273,33 +276,14 @@ sysc_do_restart: | |||
273 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) | 276 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) |
274 | 277 | ||
275 | sysc_return: | 278 | sysc_return: |
279 | LOCKDEP_SYS_EXIT | ||
280 | sysc_tif: | ||
276 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | 281 | tm __TI_flags+3(%r9),_TIF_WORK_SVC |
277 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 282 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
278 | sysc_restore: | 283 | sysc_restore: |
279 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
280 | la %r1,BASED(sysc_restore_trace_psw_addr) | ||
281 | l %r1,0(%r1) | ||
282 | lpsw 0(%r1) | ||
283 | sysc_restore_trace: | ||
284 | TRACE_IRQS_CHECK | ||
285 | LOCKDEP_SYS_EXIT | ||
286 | #endif | ||
287 | sysc_leave: | ||
288 | RESTORE_ALL __LC_RETURN_PSW,1 | 284 | RESTORE_ALL __LC_RETURN_PSW,1 |
289 | sysc_done: | 285 | sysc_done: |
290 | 286 | ||
291 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
292 | sysc_restore_trace_psw_addr: | ||
293 | .long sysc_restore_trace_psw | ||
294 | |||
295 | .section .data,"aw",@progbits | ||
296 | .align 8 | ||
297 | .globl sysc_restore_trace_psw | ||
298 | sysc_restore_trace_psw: | ||
299 | .long 0, sysc_restore_trace + 0x80000000 | ||
300 | .previous | ||
301 | #endif | ||
302 | |||
303 | # | 287 | # |
304 | # There is work to do, but first we need to check if we return to userspace. | 288 | # There is work to do, but first we need to check if we return to userspace. |
305 | # | 289 | # |
@@ -310,7 +294,7 @@ sysc_work: | |||
310 | # | 294 | # |
311 | # One of the work bits is on. Find out which one. | 295 | # One of the work bits is on. Find out which one. |
312 | # | 296 | # |
313 | sysc_work_loop: | 297 | sysc_work_tif: |
314 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 298 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING |
315 | bo BASED(sysc_mcck_pending) | 299 | bo BASED(sysc_mcck_pending) |
316 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 300 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
@@ -330,7 +314,7 @@ sysc_work_loop: | |||
330 | # | 314 | # |
331 | sysc_reschedule: | 315 | sysc_reschedule: |
332 | l %r1,BASED(.Lschedule) | 316 | l %r1,BASED(.Lschedule) |
333 | la %r14,BASED(sysc_work_loop) | 317 | la %r14,BASED(sysc_return) |
334 | br %r1 # call scheduler | 318 | br %r1 # call scheduler |
335 | 319 | ||
336 | # | 320 | # |
@@ -338,7 +322,7 @@ sysc_reschedule: | |||
338 | # | 322 | # |
339 | sysc_mcck_pending: | 323 | sysc_mcck_pending: |
340 | l %r1,BASED(.Ls390_handle_mcck) | 324 | l %r1,BASED(.Ls390_handle_mcck) |
341 | la %r14,BASED(sysc_work_loop) | 325 | la %r14,BASED(sysc_return) |
342 | br %r1 # TIF bit will be cleared by handler | 326 | br %r1 # TIF bit will be cleared by handler |
343 | 327 | ||
344 | # | 328 | # |
@@ -353,7 +337,7 @@ sysc_sigpending: | |||
353 | bo BASED(sysc_restart) | 337 | bo BASED(sysc_restart) |
354 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 338 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP |
355 | bo BASED(sysc_singlestep) | 339 | bo BASED(sysc_singlestep) |
356 | b BASED(sysc_work_loop) | 340 | b BASED(sysc_return) |
357 | 341 | ||
358 | # | 342 | # |
359 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume | 343 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume |
@@ -361,7 +345,7 @@ sysc_sigpending: | |||
361 | sysc_notify_resume: | 345 | sysc_notify_resume: |
362 | la %r2,SP_PTREGS(%r15) # load pt_regs | 346 | la %r2,SP_PTREGS(%r15) # load pt_regs |
363 | l %r1,BASED(.Ldo_notify_resume) | 347 | l %r1,BASED(.Ldo_notify_resume) |
364 | la %r14,BASED(sysc_work_loop) | 348 | la %r14,BASED(sysc_return) |
365 | br %r1 # call do_notify_resume | 349 | br %r1 # call do_notify_resume |
366 | 350 | ||
367 | 351 | ||
@@ -384,7 +368,7 @@ sysc_singlestep: | |||
384 | mvi SP_SVCNR+1(%r15),0xff | 368 | mvi SP_SVCNR+1(%r15),0xff |
385 | la %r2,SP_PTREGS(%r15) # address of register-save area | 369 | la %r2,SP_PTREGS(%r15) # address of register-save area |
386 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 370 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
387 | la %r14,BASED(sysc_work_loop) # load adr. of system return | 371 | la %r14,BASED(sysc_return) # load adr. of system return |
388 | br %r1 # branch to do_single_step | 372 | br %r1 # branch to do_single_step |
389 | 373 | ||
390 | # | 374 | # |
@@ -456,11 +440,13 @@ kernel_execve: | |||
456 | br %r14 | 440 | br %r14 |
457 | # execve succeeded. | 441 | # execve succeeded. |
458 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts | 442 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts |
443 | TRACE_IRQS_OFF | ||
459 | l %r15,__LC_KERNEL_STACK # load ksp | 444 | l %r15,__LC_KERNEL_STACK # load ksp |
460 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 445 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
461 | l %r9,__LC_THREAD_INFO | 446 | l %r9,__LC_THREAD_INFO |
462 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs | 447 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs |
463 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 448 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
449 | TRACE_IRQS_ON | ||
464 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 450 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
465 | l %r1,BASED(.Lexecve_tail) | 451 | l %r1,BASED(.Lexecve_tail) |
466 | basr %r14,%r1 | 452 | basr %r14,%r1 |
@@ -497,8 +483,8 @@ pgm_check_handler: | |||
497 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 483 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
498 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 484 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
499 | pgm_no_vtime: | 485 | pgm_no_vtime: |
486 | TRACE_IRQS_CHECK_OFF | ||
500 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 487 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
501 | TRACE_IRQS_OFF | ||
502 | l %r3,__LC_PGM_ILC # load program interruption code | 488 | l %r3,__LC_PGM_ILC # load program interruption code |
503 | la %r8,0x7f | 489 | la %r8,0x7f |
504 | nr %r8,%r3 | 490 | nr %r8,%r3 |
@@ -507,8 +493,10 @@ pgm_do_call: | |||
507 | sll %r8,2 | 493 | sll %r8,2 |
508 | l %r7,0(%r8,%r7) # load address of handler routine | 494 | l %r7,0(%r8,%r7) # load address of handler routine |
509 | la %r2,SP_PTREGS(%r15) # address of register-save area | 495 | la %r2,SP_PTREGS(%r15) # address of register-save area |
510 | la %r14,BASED(sysc_return) | 496 | basr %r14,%r7 # branch to interrupt-handler |
511 | br %r7 # branch to interrupt-handler | 497 | pgm_exit: |
498 | TRACE_IRQS_CHECK_ON | ||
499 | b BASED(sysc_return) | ||
512 | 500 | ||
513 | # | 501 | # |
514 | # handle per exception | 502 | # handle per exception |
@@ -535,19 +523,19 @@ pgm_per_std: | |||
535 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 523 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
536 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 524 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
537 | pgm_no_vtime2: | 525 | pgm_no_vtime2: |
526 | TRACE_IRQS_CHECK_OFF | ||
538 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 527 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
539 | TRACE_IRQS_OFF | ||
540 | l %r1,__TI_task(%r9) | 528 | l %r1,__TI_task(%r9) |
529 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | ||
530 | bz BASED(kernel_per) | ||
541 | mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID | 531 | mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID |
542 | mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS | 532 | mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS |
543 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID | 533 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID |
544 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 534 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
545 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | ||
546 | bz BASED(kernel_per) | ||
547 | l %r3,__LC_PGM_ILC # load program interruption code | 535 | l %r3,__LC_PGM_ILC # load program interruption code |
548 | la %r8,0x7f | 536 | la %r8,0x7f |
549 | nr %r8,%r3 # clear per-event-bit and ilc | 537 | nr %r8,%r3 # clear per-event-bit and ilc |
550 | be BASED(sysc_return) # only per or per+check ? | 538 | be BASED(pgm_exit) # only per or per+check ? |
551 | b BASED(pgm_do_call) | 539 | b BASED(pgm_do_call) |
552 | 540 | ||
553 | # | 541 | # |
@@ -568,8 +556,8 @@ pgm_svcper: | |||
568 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID | 556 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID |
569 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 557 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
570 | TRACE_IRQS_ON | 558 | TRACE_IRQS_ON |
571 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | ||
572 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 559 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
560 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | ||
573 | b BASED(sysc_do_svc) | 561 | b BASED(sysc_do_svc) |
574 | 562 | ||
575 | # | 563 | # |
@@ -580,8 +568,8 @@ kernel_per: | |||
580 | mvi SP_SVCNR+1(%r15),0xff | 568 | mvi SP_SVCNR+1(%r15),0xff |
581 | la %r2,SP_PTREGS(%r15) # address of register-save area | 569 | la %r2,SP_PTREGS(%r15) # address of register-save area |
582 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 570 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
583 | la %r14,BASED(sysc_restore)# load adr. of system return | 571 | basr %r14,%r1 # branch to do_single_step |
584 | br %r1 # branch to do_single_step | 572 | b BASED(pgm_exit) |
585 | 573 | ||
586 | /* | 574 | /* |
587 | * IO interrupt handler routine | 575 | * IO interrupt handler routine |
@@ -600,39 +588,21 @@ io_int_handler: | |||
600 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 588 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
601 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 589 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
602 | io_no_vtime: | 590 | io_no_vtime: |
603 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
604 | TRACE_IRQS_OFF | 591 | TRACE_IRQS_OFF |
592 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
605 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ | 593 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ |
606 | la %r2,SP_PTREGS(%r15) # address of register-save area | 594 | la %r2,SP_PTREGS(%r15) # address of register-save area |
607 | basr %r14,%r1 # branch to standard irq handler | 595 | basr %r14,%r1 # branch to standard irq handler |
608 | io_return: | 596 | io_return: |
597 | LOCKDEP_SYS_EXIT | ||
598 | TRACE_IRQS_ON | ||
599 | io_tif: | ||
609 | tm __TI_flags+3(%r9),_TIF_WORK_INT | 600 | tm __TI_flags+3(%r9),_TIF_WORK_INT |
610 | bnz BASED(io_work) # there is work to do (signals etc.) | 601 | bnz BASED(io_work) # there is work to do (signals etc.) |
611 | io_restore: | 602 | io_restore: |
612 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
613 | la %r1,BASED(io_restore_trace_psw_addr) | ||
614 | l %r1,0(%r1) | ||
615 | lpsw 0(%r1) | ||
616 | io_restore_trace: | ||
617 | TRACE_IRQS_CHECK | ||
618 | LOCKDEP_SYS_EXIT | ||
619 | #endif | ||
620 | io_leave: | ||
621 | RESTORE_ALL __LC_RETURN_PSW,0 | 603 | RESTORE_ALL __LC_RETURN_PSW,0 |
622 | io_done: | 604 | io_done: |
623 | 605 | ||
624 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
625 | io_restore_trace_psw_addr: | ||
626 | .long io_restore_trace_psw | ||
627 | |||
628 | .section .data,"aw",@progbits | ||
629 | .align 8 | ||
630 | .globl io_restore_trace_psw | ||
631 | io_restore_trace_psw: | ||
632 | .long 0, io_restore_trace + 0x80000000 | ||
633 | .previous | ||
634 | #endif | ||
635 | |||
636 | # | 606 | # |
637 | # There is work todo, find out in which context we have been interrupted: | 607 | # There is work todo, find out in which context we have been interrupted: |
638 | # 1) if we return to user space we can do all _TIF_WORK_INT work | 608 | # 1) if we return to user space we can do all _TIF_WORK_INT work |
@@ -647,19 +617,23 @@ io_work: | |||
647 | # check for preemptive scheduling | 617 | # check for preemptive scheduling |
648 | icm %r0,15,__TI_precount(%r9) | 618 | icm %r0,15,__TI_precount(%r9) |
649 | bnz BASED(io_restore) # preemption disabled | 619 | bnz BASED(io_restore) # preemption disabled |
620 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | ||
621 | bno BASED(io_restore) | ||
650 | # switch to kernel stack | 622 | # switch to kernel stack |
651 | l %r1,SP_R15(%r15) | 623 | l %r1,SP_R15(%r15) |
652 | s %r1,BASED(.Lc_spsize) | 624 | s %r1,BASED(.Lc_spsize) |
653 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 625 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
654 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 626 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
655 | lr %r15,%r1 | 627 | lr %r15,%r1 |
656 | io_resume_loop: | 628 | # TRACE_IRQS_ON already done at io_return, call |
629 | # TRACE_IRQS_OFF to keep things symmetrical | ||
630 | TRACE_IRQS_OFF | ||
657 | l %r1,BASED(.Lpreempt_schedule_irq) | 631 | l %r1,BASED(.Lpreempt_schedule_irq) |
658 | la %r14,BASED(io_resume_loop) | 632 | basr %r14,%r1 # call preempt_schedule_irq |
659 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 633 | b BASED(io_return) |
660 | bor %r1 # call preempt_schedule_irq | 634 | #else |
661 | #endif | ||
662 | b BASED(io_restore) | 635 | b BASED(io_restore) |
636 | #endif | ||
663 | 637 | ||
664 | # | 638 | # |
665 | # Need to do work before returning to userspace, switch to kernel stack | 639 | # Need to do work before returning to userspace, switch to kernel stack |
@@ -670,12 +644,13 @@ io_work_user: | |||
670 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 644 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
671 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 645 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
672 | lr %r15,%r1 | 646 | lr %r15,%r1 |
647 | |||
673 | # | 648 | # |
674 | # One of the work bits is on. Find out which one. | 649 | # One of the work bits is on. Find out which one. |
675 | # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED | 650 | # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED |
676 | # and _TIF_MCCK_PENDING | 651 | # and _TIF_MCCK_PENDING |
677 | # | 652 | # |
678 | io_work_loop: | 653 | io_work_tif: |
679 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 654 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING |
680 | bo BASED(io_mcck_pending) | 655 | bo BASED(io_mcck_pending) |
681 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 656 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
@@ -690,47 +665,49 @@ io_work_loop: | |||
690 | # _TIF_MCCK_PENDING is set, call handler | 665 | # _TIF_MCCK_PENDING is set, call handler |
691 | # | 666 | # |
692 | io_mcck_pending: | 667 | io_mcck_pending: |
668 | # TRACE_IRQS_ON already done at io_return | ||
693 | l %r1,BASED(.Ls390_handle_mcck) | 669 | l %r1,BASED(.Ls390_handle_mcck) |
694 | basr %r14,%r1 # TIF bit will be cleared by handler | 670 | basr %r14,%r1 # TIF bit will be cleared by handler |
695 | b BASED(io_work_loop) | 671 | TRACE_IRQS_OFF |
672 | b BASED(io_return) | ||
696 | 673 | ||
697 | # | 674 | # |
698 | # _TIF_NEED_RESCHED is set, call schedule | 675 | # _TIF_NEED_RESCHED is set, call schedule |
699 | # | 676 | # |
700 | io_reschedule: | 677 | io_reschedule: |
701 | TRACE_IRQS_ON | 678 | # TRACE_IRQS_ON already done at io_return |
702 | l %r1,BASED(.Lschedule) | 679 | l %r1,BASED(.Lschedule) |
703 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 680 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
704 | basr %r14,%r1 # call scheduler | 681 | basr %r14,%r1 # call scheduler |
705 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 682 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
706 | TRACE_IRQS_OFF | 683 | TRACE_IRQS_OFF |
707 | b BASED(io_work_loop) | 684 | b BASED(io_return) |
708 | 685 | ||
709 | # | 686 | # |
710 | # _TIF_SIGPENDING is set, call do_signal | 687 | # _TIF_SIGPENDING is set, call do_signal |
711 | # | 688 | # |
712 | io_sigpending: | 689 | io_sigpending: |
713 | TRACE_IRQS_ON | 690 | # TRACE_IRQS_ON already done at io_return |
714 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 691 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
715 | la %r2,SP_PTREGS(%r15) # load pt_regs | 692 | la %r2,SP_PTREGS(%r15) # load pt_regs |
716 | l %r1,BASED(.Ldo_signal) | 693 | l %r1,BASED(.Ldo_signal) |
717 | basr %r14,%r1 # call do_signal | 694 | basr %r14,%r1 # call do_signal |
718 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 695 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
719 | TRACE_IRQS_OFF | 696 | TRACE_IRQS_OFF |
720 | b BASED(io_work_loop) | 697 | b BASED(io_return) |
721 | 698 | ||
722 | # | 699 | # |
723 | # _TIF_SIGPENDING is set, call do_signal | 700 | # _TIF_SIGPENDING is set, call do_signal |
724 | # | 701 | # |
725 | io_notify_resume: | 702 | io_notify_resume: |
726 | TRACE_IRQS_ON | 703 | # TRACE_IRQS_ON already done at io_return |
727 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 704 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
728 | la %r2,SP_PTREGS(%r15) # load pt_regs | 705 | la %r2,SP_PTREGS(%r15) # load pt_regs |
729 | l %r1,BASED(.Ldo_notify_resume) | 706 | l %r1,BASED(.Ldo_notify_resume) |
730 | basr %r14,%r1 # call do_signal | 707 | basr %r14,%r1 # call do_signal |
731 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 708 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
732 | TRACE_IRQS_OFF | 709 | TRACE_IRQS_OFF |
733 | b BASED(io_work_loop) | 710 | b BASED(io_return) |
734 | 711 | ||
735 | /* | 712 | /* |
736 | * External interrupt handler routine | 713 | * External interrupt handler routine |
@@ -918,14 +895,14 @@ stack_overflow: | |||
918 | 895 | ||
919 | cleanup_table_system_call: | 896 | cleanup_table_system_call: |
920 | .long system_call + 0x80000000, sysc_do_svc + 0x80000000 | 897 | .long system_call + 0x80000000, sysc_do_svc + 0x80000000 |
921 | cleanup_table_sysc_return: | 898 | cleanup_table_sysc_tif: |
922 | .long sysc_return + 0x80000000, sysc_leave + 0x80000000 | 899 | .long sysc_tif + 0x80000000, sysc_restore + 0x80000000 |
923 | cleanup_table_sysc_leave: | 900 | cleanup_table_sysc_restore: |
924 | .long sysc_leave + 0x80000000, sysc_done + 0x80000000 | 901 | .long sysc_restore + 0x80000000, sysc_done + 0x80000000 |
925 | cleanup_table_io_return: | 902 | cleanup_table_io_tif: |
926 | .long io_return + 0x80000000, io_leave + 0x80000000 | 903 | .long io_tif + 0x80000000, io_restore + 0x80000000 |
927 | cleanup_table_io_leave: | 904 | cleanup_table_io_restore: |
928 | .long io_leave + 0x80000000, io_done + 0x80000000 | 905 | .long io_restore + 0x80000000, io_done + 0x80000000 |
929 | 906 | ||
930 | cleanup_critical: | 907 | cleanup_critical: |
931 | clc 4(4,%r12),BASED(cleanup_table_system_call) | 908 | clc 4(4,%r12),BASED(cleanup_table_system_call) |
@@ -933,25 +910,25 @@ cleanup_critical: | |||
933 | clc 4(4,%r12),BASED(cleanup_table_system_call+4) | 910 | clc 4(4,%r12),BASED(cleanup_table_system_call+4) |
934 | bl BASED(cleanup_system_call) | 911 | bl BASED(cleanup_system_call) |
935 | 0: | 912 | 0: |
936 | clc 4(4,%r12),BASED(cleanup_table_sysc_return) | 913 | clc 4(4,%r12),BASED(cleanup_table_sysc_tif) |
937 | bl BASED(0f) | 914 | bl BASED(0f) |
938 | clc 4(4,%r12),BASED(cleanup_table_sysc_return+4) | 915 | clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4) |
939 | bl BASED(cleanup_sysc_return) | 916 | bl BASED(cleanup_sysc_tif) |
940 | 0: | 917 | 0: |
941 | clc 4(4,%r12),BASED(cleanup_table_sysc_leave) | 918 | clc 4(4,%r12),BASED(cleanup_table_sysc_restore) |
942 | bl BASED(0f) | 919 | bl BASED(0f) |
943 | clc 4(4,%r12),BASED(cleanup_table_sysc_leave+4) | 920 | clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4) |
944 | bl BASED(cleanup_sysc_leave) | 921 | bl BASED(cleanup_sysc_restore) |
945 | 0: | 922 | 0: |
946 | clc 4(4,%r12),BASED(cleanup_table_io_return) | 923 | clc 4(4,%r12),BASED(cleanup_table_io_tif) |
947 | bl BASED(0f) | 924 | bl BASED(0f) |
948 | clc 4(4,%r12),BASED(cleanup_table_io_return+4) | 925 | clc 4(4,%r12),BASED(cleanup_table_io_tif+4) |
949 | bl BASED(cleanup_io_return) | 926 | bl BASED(cleanup_io_tif) |
950 | 0: | 927 | 0: |
951 | clc 4(4,%r12),BASED(cleanup_table_io_leave) | 928 | clc 4(4,%r12),BASED(cleanup_table_io_restore) |
952 | bl BASED(0f) | 929 | bl BASED(0f) |
953 | clc 4(4,%r12),BASED(cleanup_table_io_leave+4) | 930 | clc 4(4,%r12),BASED(cleanup_table_io_restore+4) |
954 | bl BASED(cleanup_io_leave) | 931 | bl BASED(cleanup_io_restore) |
955 | 0: | 932 | 0: |
956 | br %r14 | 933 | br %r14 |
957 | 934 | ||
@@ -998,17 +975,17 @@ cleanup_system_call_insn: | |||
998 | .long sysc_stime + 0x80000000 | 975 | .long sysc_stime + 0x80000000 |
999 | .long sysc_update + 0x80000000 | 976 | .long sysc_update + 0x80000000 |
1000 | 977 | ||
1001 | cleanup_sysc_return: | 978 | cleanup_sysc_tif: |
1002 | mvc __LC_RETURN_PSW(4),0(%r12) | 979 | mvc __LC_RETURN_PSW(4),0(%r12) |
1003 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_return) | 980 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif) |
1004 | la %r12,__LC_RETURN_PSW | 981 | la %r12,__LC_RETURN_PSW |
1005 | br %r14 | 982 | br %r14 |
1006 | 983 | ||
1007 | cleanup_sysc_leave: | 984 | cleanup_sysc_restore: |
1008 | clc 4(4,%r12),BASED(cleanup_sysc_leave_insn) | 985 | clc 4(4,%r12),BASED(cleanup_sysc_restore_insn) |
1009 | be BASED(2f) | 986 | be BASED(2f) |
1010 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER | 987 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER |
1011 | clc 4(4,%r12),BASED(cleanup_sysc_leave_insn+4) | 988 | clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) |
1012 | be BASED(2f) | 989 | be BASED(2f) |
1013 | mvc __LC_RETURN_PSW(8),SP_PSW(%r15) | 990 | mvc __LC_RETURN_PSW(8),SP_PSW(%r15) |
1014 | c %r12,BASED(.Lmck_old_psw) | 991 | c %r12,BASED(.Lmck_old_psw) |
@@ -1020,21 +997,21 @@ cleanup_sysc_leave: | |||
1020 | l %r15,SP_R15(%r15) | 997 | l %r15,SP_R15(%r15) |
1021 | 2: la %r12,__LC_RETURN_PSW | 998 | 2: la %r12,__LC_RETURN_PSW |
1022 | br %r14 | 999 | br %r14 |
1023 | cleanup_sysc_leave_insn: | 1000 | cleanup_sysc_restore_insn: |
1024 | .long sysc_done - 4 + 0x80000000 | 1001 | .long sysc_done - 4 + 0x80000000 |
1025 | .long sysc_done - 8 + 0x80000000 | 1002 | .long sysc_done - 8 + 0x80000000 |
1026 | 1003 | ||
1027 | cleanup_io_return: | 1004 | cleanup_io_tif: |
1028 | mvc __LC_RETURN_PSW(4),0(%r12) | 1005 | mvc __LC_RETURN_PSW(4),0(%r12) |
1029 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return) | 1006 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif) |
1030 | la %r12,__LC_RETURN_PSW | 1007 | la %r12,__LC_RETURN_PSW |
1031 | br %r14 | 1008 | br %r14 |
1032 | 1009 | ||
1033 | cleanup_io_leave: | 1010 | cleanup_io_restore: |
1034 | clc 4(4,%r12),BASED(cleanup_io_leave_insn) | 1011 | clc 4(4,%r12),BASED(cleanup_io_restore_insn) |
1035 | be BASED(2f) | 1012 | be BASED(2f) |
1036 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER | 1013 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER |
1037 | clc 4(4,%r12),BASED(cleanup_io_leave_insn+4) | 1014 | clc 4(4,%r12),BASED(cleanup_io_restore_insn+4) |
1038 | be BASED(2f) | 1015 | be BASED(2f) |
1039 | mvc __LC_RETURN_PSW(8),SP_PSW(%r15) | 1016 | mvc __LC_RETURN_PSW(8),SP_PSW(%r15) |
1040 | c %r12,BASED(.Lmck_old_psw) | 1017 | c %r12,BASED(.Lmck_old_psw) |
@@ -1046,7 +1023,7 @@ cleanup_io_leave: | |||
1046 | l %r15,SP_R15(%r15) | 1023 | l %r15,SP_R15(%r15) |
1047 | 2: la %r12,__LC_RETURN_PSW | 1024 | 2: la %r12,__LC_RETURN_PSW |
1048 | br %r14 | 1025 | br %r14 |
1049 | cleanup_io_leave_insn: | 1026 | cleanup_io_restore_insn: |
1050 | .long io_done - 4 + 0x80000000 | 1027 | .long io_done - 4 + 0x80000000 |
1051 | .long io_done - 8 + 0x80000000 | 1028 | .long io_done - 8 + 0x80000000 |
1052 | 1029 | ||
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index ca02b10a2c32..860cea1d1c8a 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -61,28 +61,33 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | |||
61 | 61 | ||
62 | #ifdef CONFIG_TRACE_IRQFLAGS | 62 | #ifdef CONFIG_TRACE_IRQFLAGS |
63 | .macro TRACE_IRQS_ON | 63 | .macro TRACE_IRQS_ON |
64 | basr %r2,%r0 | 64 | basr %r2,%r0 |
65 | brasl %r14,trace_hardirqs_on_caller | 65 | brasl %r14,trace_hardirqs_on_caller |
66 | .endm | 66 | .endm |
67 | 67 | ||
68 | .macro TRACE_IRQS_OFF | 68 | .macro TRACE_IRQS_OFF |
69 | basr %r2,%r0 | 69 | basr %r2,%r0 |
70 | brasl %r14,trace_hardirqs_off_caller | 70 | brasl %r14,trace_hardirqs_off_caller |
71 | .endm | 71 | .endm |
72 | 72 | ||
73 | .macro TRACE_IRQS_CHECK | 73 | .macro TRACE_IRQS_CHECK_ON |
74 | basr %r2,%r0 | ||
75 | tm SP_PSW(%r15),0x03 # irqs enabled? | 74 | tm SP_PSW(%r15),0x03 # irqs enabled? |
76 | jz 0f | 75 | jz 0f |
77 | brasl %r14,trace_hardirqs_on_caller | 76 | TRACE_IRQS_ON |
78 | j 1f | 77 | 0: |
79 | 0: brasl %r14,trace_hardirqs_off_caller | 78 | .endm |
80 | 1: | 79 | |
80 | .macro TRACE_IRQS_CHECK_OFF | ||
81 | tm SP_PSW(%r15),0x03 # irqs enabled? | ||
82 | jz 0f | ||
83 | TRACE_IRQS_OFF | ||
84 | 0: | ||
81 | .endm | 85 | .endm |
82 | #else | 86 | #else |
83 | #define TRACE_IRQS_ON | 87 | #define TRACE_IRQS_ON |
84 | #define TRACE_IRQS_OFF | 88 | #define TRACE_IRQS_OFF |
85 | #define TRACE_IRQS_CHECK | 89 | #define TRACE_IRQS_CHECK_ON |
90 | #define TRACE_IRQS_CHECK_OFF | ||
86 | #endif | 91 | #endif |
87 | 92 | ||
88 | #ifdef CONFIG_LOCKDEP | 93 | #ifdef CONFIG_LOCKDEP |
@@ -267,29 +272,14 @@ sysc_noemu: | |||
267 | stg %r2,SP_R2(%r15) # store return value (change R2 on stack) | 272 | stg %r2,SP_R2(%r15) # store return value (change R2 on stack) |
268 | 273 | ||
269 | sysc_return: | 274 | sysc_return: |
275 | LOCKDEP_SYS_EXIT | ||
276 | sysc_tif: | ||
270 | tm __TI_flags+7(%r9),_TIF_WORK_SVC | 277 | tm __TI_flags+7(%r9),_TIF_WORK_SVC |
271 | jnz sysc_work # there is work to do (signals etc.) | 278 | jnz sysc_work # there is work to do (signals etc.) |
272 | sysc_restore: | 279 | sysc_restore: |
273 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
274 | larl %r1,sysc_restore_trace_psw | ||
275 | lpswe 0(%r1) | ||
276 | sysc_restore_trace: | ||
277 | TRACE_IRQS_CHECK | ||
278 | LOCKDEP_SYS_EXIT | ||
279 | #endif | ||
280 | sysc_leave: | ||
281 | RESTORE_ALL __LC_RETURN_PSW,1 | 280 | RESTORE_ALL __LC_RETURN_PSW,1 |
282 | sysc_done: | 281 | sysc_done: |
283 | 282 | ||
284 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
285 | .section .data,"aw",@progbits | ||
286 | .align 8 | ||
287 | .globl sysc_restore_trace_psw | ||
288 | sysc_restore_trace_psw: | ||
289 | .quad 0, sysc_restore_trace | ||
290 | .previous | ||
291 | #endif | ||
292 | |||
293 | # | 283 | # |
294 | # There is work to do, but first we need to check if we return to userspace. | 284 | # There is work to do, but first we need to check if we return to userspace. |
295 | # | 285 | # |
@@ -300,7 +290,7 @@ sysc_work: | |||
300 | # | 290 | # |
301 | # One of the work bits is on. Find out which one. | 291 | # One of the work bits is on. Find out which one. |
302 | # | 292 | # |
303 | sysc_work_loop: | 293 | sysc_work_tif: |
304 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | 294 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING |
305 | jo sysc_mcck_pending | 295 | jo sysc_mcck_pending |
306 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED | 296 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED |
@@ -319,14 +309,14 @@ sysc_work_loop: | |||
319 | # _TIF_NEED_RESCHED is set, call schedule | 309 | # _TIF_NEED_RESCHED is set, call schedule |
320 | # | 310 | # |
321 | sysc_reschedule: | 311 | sysc_reschedule: |
322 | larl %r14,sysc_work_loop | 312 | larl %r14,sysc_return |
323 | jg schedule # return point is sysc_work_loop | 313 | jg schedule # return point is sysc_return |
324 | 314 | ||
325 | # | 315 | # |
326 | # _TIF_MCCK_PENDING is set, call handler | 316 | # _TIF_MCCK_PENDING is set, call handler |
327 | # | 317 | # |
328 | sysc_mcck_pending: | 318 | sysc_mcck_pending: |
329 | larl %r14,sysc_work_loop | 319 | larl %r14,sysc_return |
330 | jg s390_handle_mcck # TIF bit will be cleared by handler | 320 | jg s390_handle_mcck # TIF bit will be cleared by handler |
331 | 321 | ||
332 | # | 322 | # |
@@ -340,14 +330,14 @@ sysc_sigpending: | |||
340 | jo sysc_restart | 330 | jo sysc_restart |
341 | tm __TI_flags+7(%r9),_TIF_SINGLE_STEP | 331 | tm __TI_flags+7(%r9),_TIF_SINGLE_STEP |
342 | jo sysc_singlestep | 332 | jo sysc_singlestep |
343 | j sysc_work_loop | 333 | j sysc_return |
344 | 334 | ||
345 | # | 335 | # |
346 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume | 336 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume |
347 | # | 337 | # |
348 | sysc_notify_resume: | 338 | sysc_notify_resume: |
349 | la %r2,SP_PTREGS(%r15) # load pt_regs | 339 | la %r2,SP_PTREGS(%r15) # load pt_regs |
350 | larl %r14,sysc_work_loop | 340 | larl %r14,sysc_return |
351 | jg do_notify_resume # call do_notify_resume | 341 | jg do_notify_resume # call do_notify_resume |
352 | 342 | ||
353 | # | 343 | # |
@@ -367,7 +357,7 @@ sysc_singlestep: | |||
367 | ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP | 357 | ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP |
368 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number | 358 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number |
369 | la %r2,SP_PTREGS(%r15) # address of register-save area | 359 | la %r2,SP_PTREGS(%r15) # address of register-save area |
370 | larl %r14,sysc_work_loop # load adr. of system return | 360 | larl %r14,sysc_return # load adr. of system return |
371 | jg do_single_step # branch to do_sigtrap | 361 | jg do_single_step # branch to do_sigtrap |
372 | 362 | ||
373 | # | 363 | # |
@@ -433,12 +423,14 @@ kernel_execve: | |||
433 | br %r14 | 423 | br %r14 |
434 | # execve succeeded. | 424 | # execve succeeded. |
435 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts | 425 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts |
426 | # TRACE_IRQS_OFF | ||
436 | lg %r15,__LC_KERNEL_STACK # load ksp | 427 | lg %r15,__LC_KERNEL_STACK # load ksp |
437 | aghi %r15,-SP_SIZE # make room for registers & psw | 428 | aghi %r15,-SP_SIZE # make room for registers & psw |
438 | lg %r13,__LC_SVC_NEW_PSW+8 | 429 | lg %r13,__LC_SVC_NEW_PSW+8 |
439 | lg %r9,__LC_THREAD_INFO | 430 | lg %r9,__LC_THREAD_INFO |
440 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs | 431 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs |
441 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 432 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
433 | # TRACE_IRQS_ON | ||
442 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 434 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
443 | brasl %r14,execve_tail | 435 | brasl %r14,execve_tail |
444 | j sysc_return | 436 | j sysc_return |
@@ -474,9 +466,9 @@ pgm_check_handler: | |||
474 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 466 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
475 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 467 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
476 | pgm_no_vtime: | 468 | pgm_no_vtime: |
469 | TRACE_IRQS_CHECK_OFF | ||
477 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 470 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
478 | mvc SP_ARGS(8,%r15),__LC_LAST_BREAK | 471 | mvc SP_ARGS(8,%r15),__LC_LAST_BREAK |
479 | TRACE_IRQS_OFF | ||
480 | lgf %r3,__LC_PGM_ILC # load program interruption code | 472 | lgf %r3,__LC_PGM_ILC # load program interruption code |
481 | lghi %r8,0x7f | 473 | lghi %r8,0x7f |
482 | ngr %r8,%r3 | 474 | ngr %r8,%r3 |
@@ -485,8 +477,10 @@ pgm_do_call: | |||
485 | larl %r1,pgm_check_table | 477 | larl %r1,pgm_check_table |
486 | lg %r1,0(%r8,%r1) # load address of handler routine | 478 | lg %r1,0(%r8,%r1) # load address of handler routine |
487 | la %r2,SP_PTREGS(%r15) # address of register-save area | 479 | la %r2,SP_PTREGS(%r15) # address of register-save area |
488 | larl %r14,sysc_return | 480 | basr %r14,%r1 # branch to interrupt-handler |
489 | br %r1 # branch to interrupt-handler | 481 | pgm_exit: |
482 | TRACE_IRQS_CHECK_ON | ||
483 | j sysc_return | ||
490 | 484 | ||
491 | # | 485 | # |
492 | # handle per exception | 486 | # handle per exception |
@@ -513,8 +507,8 @@ pgm_per_std: | |||
513 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 507 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
514 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 508 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
515 | pgm_no_vtime2: | 509 | pgm_no_vtime2: |
510 | TRACE_IRQS_CHECK_OFF | ||
516 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 511 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
517 | TRACE_IRQS_OFF | ||
518 | lg %r1,__TI_task(%r9) | 512 | lg %r1,__TI_task(%r9) |
519 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | 513 | tm SP_PSW+1(%r15),0x01 # kernel per event ? |
520 | jz kernel_per | 514 | jz kernel_per |
@@ -525,7 +519,7 @@ pgm_no_vtime2: | |||
525 | lgf %r3,__LC_PGM_ILC # load program interruption code | 519 | lgf %r3,__LC_PGM_ILC # load program interruption code |
526 | lghi %r8,0x7f | 520 | lghi %r8,0x7f |
527 | ngr %r8,%r3 # clear per-event-bit and ilc | 521 | ngr %r8,%r3 # clear per-event-bit and ilc |
528 | je sysc_return | 522 | je pgm_exit |
529 | j pgm_do_call | 523 | j pgm_do_call |
530 | 524 | ||
531 | # | 525 | # |
@@ -539,14 +533,15 @@ pgm_svcper: | |||
539 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 533 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
540 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore | 534 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore |
541 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 535 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
536 | TRACE_IRQS_OFF | ||
542 | lg %r8,__TI_task(%r9) | 537 | lg %r8,__TI_task(%r9) |
543 | mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID | 538 | mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID |
544 | mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS | 539 | mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS |
545 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID | 540 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID |
546 | oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 541 | oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
547 | TRACE_IRQS_ON | 542 | TRACE_IRQS_ON |
548 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments | ||
549 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 543 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
544 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments | ||
550 | j sysc_do_svc | 545 | j sysc_do_svc |
551 | 546 | ||
552 | # | 547 | # |
@@ -555,8 +550,8 @@ pgm_svcper: | |||
555 | kernel_per: | 550 | kernel_per: |
556 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number | 551 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number |
557 | la %r2,SP_PTREGS(%r15) # address of register-save area | 552 | la %r2,SP_PTREGS(%r15) # address of register-save area |
558 | larl %r14,sysc_restore # load adr. of system ret, no work | 553 | brasl %r14,do_single_step |
559 | jg do_single_step # branch to do_single_step | 554 | j pgm_exit |
560 | 555 | ||
561 | /* | 556 | /* |
562 | * IO interrupt handler routine | 557 | * IO interrupt handler routine |
@@ -579,29 +574,15 @@ io_no_vtime: | |||
579 | la %r2,SP_PTREGS(%r15) # address of register-save area | 574 | la %r2,SP_PTREGS(%r15) # address of register-save area |
580 | brasl %r14,do_IRQ # call standard irq handler | 575 | brasl %r14,do_IRQ # call standard irq handler |
581 | io_return: | 576 | io_return: |
577 | LOCKDEP_SYS_EXIT | ||
578 | TRACE_IRQS_ON | ||
579 | io_tif: | ||
582 | tm __TI_flags+7(%r9),_TIF_WORK_INT | 580 | tm __TI_flags+7(%r9),_TIF_WORK_INT |
583 | jnz io_work # there is work to do (signals etc.) | 581 | jnz io_work # there is work to do (signals etc.) |
584 | io_restore: | 582 | io_restore: |
585 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
586 | larl %r1,io_restore_trace_psw | ||
587 | lpswe 0(%r1) | ||
588 | io_restore_trace: | ||
589 | TRACE_IRQS_CHECK | ||
590 | LOCKDEP_SYS_EXIT | ||
591 | #endif | ||
592 | io_leave: | ||
593 | RESTORE_ALL __LC_RETURN_PSW,0 | 583 | RESTORE_ALL __LC_RETURN_PSW,0 |
594 | io_done: | 584 | io_done: |
595 | 585 | ||
596 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
597 | .section .data,"aw",@progbits | ||
598 | .align 8 | ||
599 | .globl io_restore_trace_psw | ||
600 | io_restore_trace_psw: | ||
601 | .quad 0, io_restore_trace | ||
602 | .previous | ||
603 | #endif | ||
604 | |||
605 | # | 586 | # |
606 | # There is work todo, find out in which context we have been interrupted: | 587 | # There is work todo, find out in which context we have been interrupted: |
607 | # 1) if we return to user space we can do all _TIF_WORK_INT work | 588 | # 1) if we return to user space we can do all _TIF_WORK_INT work |
@@ -627,18 +608,22 @@ io_work: | |||
627 | # check for preemptive scheduling | 608 | # check for preemptive scheduling |
628 | icm %r0,15,__TI_precount(%r9) | 609 | icm %r0,15,__TI_precount(%r9) |
629 | jnz io_restore # preemption is disabled | 610 | jnz io_restore # preemption is disabled |
611 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED | ||
612 | jno io_restore | ||
630 | # switch to kernel stack | 613 | # switch to kernel stack |
631 | lg %r1,SP_R15(%r15) | 614 | lg %r1,SP_R15(%r15) |
632 | aghi %r1,-SP_SIZE | 615 | aghi %r1,-SP_SIZE |
633 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 616 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
634 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 617 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
635 | lgr %r15,%r1 | 618 | lgr %r15,%r1 |
636 | io_resume_loop: | 619 | # TRACE_IRQS_ON already done at io_return, call |
637 | larl %r14,io_resume_loop | 620 | # TRACE_IRQS_OFF to keep things symmetrical |
638 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED | 621 | TRACE_IRQS_OFF |
639 | jgo preempt_schedule_irq | 622 | brasl %r14,preempt_schedule_irq |
640 | #endif | 623 | j io_return |
624 | #else | ||
641 | j io_restore | 625 | j io_restore |
626 | #endif | ||
642 | 627 | ||
643 | # | 628 | # |
644 | # Need to do work before returning to userspace, switch to kernel stack | 629 | # Need to do work before returning to userspace, switch to kernel stack |
@@ -655,7 +640,7 @@ io_work_user: | |||
655 | # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED | 640 | # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED |
656 | # and _TIF_MCCK_PENDING | 641 | # and _TIF_MCCK_PENDING |
657 | # | 642 | # |
658 | io_work_loop: | 643 | io_work_tif: |
659 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | 644 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING |
660 | jo io_mcck_pending | 645 | jo io_mcck_pending |
661 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED | 646 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED |
@@ -670,43 +655,45 @@ io_work_loop: | |||
670 | # _TIF_MCCK_PENDING is set, call handler | 655 | # _TIF_MCCK_PENDING is set, call handler |
671 | # | 656 | # |
672 | io_mcck_pending: | 657 | io_mcck_pending: |
658 | # TRACE_IRQS_ON already done at io_return | ||
673 | brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler | 659 | brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler |
674 | j io_work_loop | 660 | TRACE_IRQS_OFF |
661 | j io_return | ||
675 | 662 | ||
676 | # | 663 | # |
677 | # _TIF_NEED_RESCHED is set, call schedule | 664 | # _TIF_NEED_RESCHED is set, call schedule |
678 | # | 665 | # |
679 | io_reschedule: | 666 | io_reschedule: |
680 | TRACE_IRQS_ON | 667 | # TRACE_IRQS_ON already done at io_return |
681 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 668 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
682 | brasl %r14,schedule # call scheduler | 669 | brasl %r14,schedule # call scheduler |
683 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 670 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
684 | TRACE_IRQS_OFF | 671 | TRACE_IRQS_OFF |
685 | j io_work_loop | 672 | j io_return |
686 | 673 | ||
687 | # | 674 | # |
688 | # _TIF_SIGPENDING or is set, call do_signal | 675 | # _TIF_SIGPENDING or is set, call do_signal |
689 | # | 676 | # |
690 | io_sigpending: | 677 | io_sigpending: |
691 | TRACE_IRQS_ON | 678 | # TRACE_IRQS_ON already done at io_return |
692 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 679 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
693 | la %r2,SP_PTREGS(%r15) # load pt_regs | 680 | la %r2,SP_PTREGS(%r15) # load pt_regs |
694 | brasl %r14,do_signal # call do_signal | 681 | brasl %r14,do_signal # call do_signal |
695 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 682 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
696 | TRACE_IRQS_OFF | 683 | TRACE_IRQS_OFF |
697 | j io_work_loop | 684 | j io_return |
698 | 685 | ||
699 | # | 686 | # |
700 | # _TIF_NOTIFY_RESUME or is set, call do_notify_resume | 687 | # _TIF_NOTIFY_RESUME or is set, call do_notify_resume |
701 | # | 688 | # |
702 | io_notify_resume: | 689 | io_notify_resume: |
703 | TRACE_IRQS_ON | 690 | # TRACE_IRQS_ON already done at io_return |
704 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 691 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
705 | la %r2,SP_PTREGS(%r15) # load pt_regs | 692 | la %r2,SP_PTREGS(%r15) # load pt_regs |
706 | brasl %r14,do_notify_resume # call do_notify_resume | 693 | brasl %r14,do_notify_resume # call do_notify_resume |
707 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 694 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
708 | TRACE_IRQS_OFF | 695 | TRACE_IRQS_OFF |
709 | j io_work_loop | 696 | j io_return |
710 | 697 | ||
711 | /* | 698 | /* |
712 | * External interrupt handler routine | 699 | * External interrupt handler routine |
@@ -883,14 +870,14 @@ stack_overflow: | |||
883 | 870 | ||
884 | cleanup_table_system_call: | 871 | cleanup_table_system_call: |
885 | .quad system_call, sysc_do_svc | 872 | .quad system_call, sysc_do_svc |
886 | cleanup_table_sysc_return: | 873 | cleanup_table_sysc_tif: |
887 | .quad sysc_return, sysc_leave | 874 | .quad sysc_tif, sysc_restore |
888 | cleanup_table_sysc_leave: | 875 | cleanup_table_sysc_restore: |
889 | .quad sysc_leave, sysc_done | 876 | .quad sysc_restore, sysc_done |
890 | cleanup_table_io_return: | 877 | cleanup_table_io_tif: |
891 | .quad io_return, io_leave | 878 | .quad io_tif, io_restore |
892 | cleanup_table_io_leave: | 879 | cleanup_table_io_restore: |
893 | .quad io_leave, io_done | 880 | .quad io_restore, io_done |
894 | 881 | ||
895 | cleanup_critical: | 882 | cleanup_critical: |
896 | clc 8(8,%r12),BASED(cleanup_table_system_call) | 883 | clc 8(8,%r12),BASED(cleanup_table_system_call) |
@@ -898,25 +885,25 @@ cleanup_critical: | |||
898 | clc 8(8,%r12),BASED(cleanup_table_system_call+8) | 885 | clc 8(8,%r12),BASED(cleanup_table_system_call+8) |
899 | jl cleanup_system_call | 886 | jl cleanup_system_call |
900 | 0: | 887 | 0: |
901 | clc 8(8,%r12),BASED(cleanup_table_sysc_return) | 888 | clc 8(8,%r12),BASED(cleanup_table_sysc_tif) |
902 | jl 0f | 889 | jl 0f |
903 | clc 8(8,%r12),BASED(cleanup_table_sysc_return+8) | 890 | clc 8(8,%r12),BASED(cleanup_table_sysc_tif+8) |
904 | jl cleanup_sysc_return | 891 | jl cleanup_sysc_tif |
905 | 0: | 892 | 0: |
906 | clc 8(8,%r12),BASED(cleanup_table_sysc_leave) | 893 | clc 8(8,%r12),BASED(cleanup_table_sysc_restore) |
907 | jl 0f | 894 | jl 0f |
908 | clc 8(8,%r12),BASED(cleanup_table_sysc_leave+8) | 895 | clc 8(8,%r12),BASED(cleanup_table_sysc_restore+8) |
909 | jl cleanup_sysc_leave | 896 | jl cleanup_sysc_restore |
910 | 0: | 897 | 0: |
911 | clc 8(8,%r12),BASED(cleanup_table_io_return) | 898 | clc 8(8,%r12),BASED(cleanup_table_io_tif) |
912 | jl 0f | 899 | jl 0f |
913 | clc 8(8,%r12),BASED(cleanup_table_io_return+8) | 900 | clc 8(8,%r12),BASED(cleanup_table_io_tif+8) |
914 | jl cleanup_io_return | 901 | jl cleanup_io_tif |
915 | 0: | 902 | 0: |
916 | clc 8(8,%r12),BASED(cleanup_table_io_leave) | 903 | clc 8(8,%r12),BASED(cleanup_table_io_restore) |
917 | jl 0f | 904 | jl 0f |
918 | clc 8(8,%r12),BASED(cleanup_table_io_leave+8) | 905 | clc 8(8,%r12),BASED(cleanup_table_io_restore+8) |
919 | jl cleanup_io_leave | 906 | jl cleanup_io_restore |
920 | 0: | 907 | 0: |
921 | br %r14 | 908 | br %r14 |
922 | 909 | ||
@@ -963,16 +950,16 @@ cleanup_system_call_insn: | |||
963 | .quad sysc_stime | 950 | .quad sysc_stime |
964 | .quad sysc_update | 951 | .quad sysc_update |
965 | 952 | ||
966 | cleanup_sysc_return: | 953 | cleanup_sysc_tif: |
967 | mvc __LC_RETURN_PSW(8),0(%r12) | 954 | mvc __LC_RETURN_PSW(8),0(%r12) |
968 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_return) | 955 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif) |
969 | la %r12,__LC_RETURN_PSW | 956 | la %r12,__LC_RETURN_PSW |
970 | br %r14 | 957 | br %r14 |
971 | 958 | ||
972 | cleanup_sysc_leave: | 959 | cleanup_sysc_restore: |
973 | clc 8(8,%r12),BASED(cleanup_sysc_leave_insn) | 960 | clc 8(8,%r12),BASED(cleanup_sysc_restore_insn) |
974 | je 3f | 961 | je 3f |
975 | clc 8(8,%r12),BASED(cleanup_sysc_leave_insn+8) | 962 | clc 8(8,%r12),BASED(cleanup_sysc_restore_insn+8) |
976 | jhe 0f | 963 | jhe 0f |
977 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER | 964 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER |
978 | 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) | 965 | 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) |
@@ -985,20 +972,20 @@ cleanup_sysc_leave: | |||
985 | lg %r15,SP_R15(%r15) | 972 | lg %r15,SP_R15(%r15) |
986 | 3: la %r12,__LC_RETURN_PSW | 973 | 3: la %r12,__LC_RETURN_PSW |
987 | br %r14 | 974 | br %r14 |
988 | cleanup_sysc_leave_insn: | 975 | cleanup_sysc_restore_insn: |
989 | .quad sysc_done - 4 | 976 | .quad sysc_done - 4 |
990 | .quad sysc_done - 16 | 977 | .quad sysc_done - 16 |
991 | 978 | ||
992 | cleanup_io_return: | 979 | cleanup_io_tif: |
993 | mvc __LC_RETURN_PSW(8),0(%r12) | 980 | mvc __LC_RETURN_PSW(8),0(%r12) |
994 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return) | 981 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif) |
995 | la %r12,__LC_RETURN_PSW | 982 | la %r12,__LC_RETURN_PSW |
996 | br %r14 | 983 | br %r14 |
997 | 984 | ||
998 | cleanup_io_leave: | 985 | cleanup_io_restore: |
999 | clc 8(8,%r12),BASED(cleanup_io_leave_insn) | 986 | clc 8(8,%r12),BASED(cleanup_io_restore_insn) |
1000 | je 3f | 987 | je 3f |
1001 | clc 8(8,%r12),BASED(cleanup_io_leave_insn+8) | 988 | clc 8(8,%r12),BASED(cleanup_io_restore_insn+8) |
1002 | jhe 0f | 989 | jhe 0f |
1003 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER | 990 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER |
1004 | 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) | 991 | 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) |
@@ -1011,7 +998,7 @@ cleanup_io_leave: | |||
1011 | lg %r15,SP_R15(%r15) | 998 | lg %r15,SP_R15(%r15) |
1012 | 3: la %r12,__LC_RETURN_PSW | 999 | 3: la %r12,__LC_RETURN_PSW |
1013 | br %r14 | 1000 | br %r14 |
1014 | cleanup_io_leave_insn: | 1001 | cleanup_io_restore_insn: |
1015 | .quad io_done - 4 | 1002 | .quad io_done - 4 |
1016 | .quad io_done - 16 | 1003 | .quad io_done - 16 |
1017 | 1004 | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 6309276516b9..598752499c3e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -369,10 +369,6 @@ static void setup_addressing_mode(void) | |||
369 | pr_info("Address spaces switched, " | 369 | pr_info("Address spaces switched, " |
370 | "mvcos not available\n"); | 370 | "mvcos not available\n"); |
371 | } | 371 | } |
372 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
373 | sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; | ||
374 | io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; | ||
375 | #endif | ||
376 | } | 372 | } |
377 | 373 | ||
378 | static void __init | 374 | static void __init |