Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Martin Schwidefsky and committed by
Martin Schwidefsky
6a2df3a8 43d399d2

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