aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2007-11-20 05:13:32 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2007-11-20 05:13:45 -0500
commit411788ea7fca01ee803af8225ac35807b4d02050 (patch)
treea9704a068513b438bbe33b219ef9f6c29be01918
parent7aa8dac7ac68f5c2293e2ecf5ef542aa849f541f (diff)
[S390] Fix irq tracing and lockdep_sys_exit calls.
Current support for TRACE_IRQFLAGS and lockdep_sys_exit is broken. IRQ flag tracing is broken for program checks. Even worse is that the newly introduced calls to lockdep_sys_exit are in the critical section code which is not supposed to call any C functions. In addition the checks if locks are still held are also done when returning to kernel code which is broken as well. Fix all this by disabling interrupts and machine checks at the exit paths and then do the appropriate checks and calls. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/entry.S109
-rw-r--r--arch/s390/kernel/entry64.S106
-rw-r--r--arch/s390/kernel/setup.c4
-rw-r--r--include/asm-s390/system.h5
4 files changed, 158 insertions, 66 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 139ca153d5cc..764d56177cb5 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -69,13 +69,31 @@ STACK_SIZE = 1 << STACK_SHIFT
69 basr %r14,%r1 69 basr %r14,%r1
70 .endm 70 .endm
71 71
72 .macro LOCKDEP_SYS_EXIT 72 .macro TRACE_IRQS_CHECK
73 l %r1,BASED(.Llockdep_sys_exit) 73 tm SP_PSW(%r15),0x03 # irqs enabled?
74 jz 0f
75 l %r1,BASED(.Ltrace_irq_on)
74 basr %r14,%r1 76 basr %r14,%r1
77 j 1f
780: l %r1,BASED(.Ltrace_irq_off)
79 basr %r14,%r1
801:
75 .endm 81 .endm
76#else 82#else
77#define TRACE_IRQS_ON 83#define TRACE_IRQS_ON
78#define TRACE_IRQS_OFF 84#define TRACE_IRQS_OFF
85#define TRACE_IRQS_CHECK
86#endif
87
88#ifdef CONFIG_LOCKDEP
89 .macro LOCKDEP_SYS_EXIT
90 tm SP_PSW+1(%r15),0x01 # returning to user ?
91 jz 0f
92 l %r1,BASED(.Llockdep_sys_exit)
93 basr %r14,%r1
940:
95 .endm
96#else
79#define LOCKDEP_SYS_EXIT 97#define LOCKDEP_SYS_EXIT
80#endif 98#endif
81 99
@@ -234,8 +252,6 @@ sysc_saveall:
234 lh %r7,0x8a # get svc number from lowcore 252 lh %r7,0x8a # get svc number from lowcore
235#ifdef CONFIG_VIRT_CPU_ACCOUNTING 253#ifdef CONFIG_VIRT_CPU_ACCOUNTING
236sysc_vtime: 254sysc_vtime:
237 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
238 bz BASED(sysc_do_svc)
239 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 255 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
240sysc_stime: 256sysc_stime:
241 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 257 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -263,19 +279,34 @@ sysc_do_restart:
263 279
264sysc_return: 280sysc_return:
265 tm SP_PSW+1(%r15),0x01 # returning to user ? 281 tm SP_PSW+1(%r15),0x01 # returning to user ?
266 bno BASED(sysc_leave) 282 bno BASED(sysc_restore)
267 tm __TI_flags+3(%r9),_TIF_WORK_SVC 283 tm __TI_flags+3(%r9),_TIF_WORK_SVC
268 bnz BASED(sysc_work) # there is work to do (signals etc.) 284 bnz BASED(sysc_work) # there is work to do (signals etc.)
285sysc_restore:
286#ifdef CONFIG_TRACE_IRQFLAGS
287 la %r1,BASED(sysc_restore_trace_psw)
288 lpsw 0(%r1)
289sysc_restore_trace:
290 TRACE_IRQS_CHECK
269 LOCKDEP_SYS_EXIT 291 LOCKDEP_SYS_EXIT
292#endif
270sysc_leave: 293sysc_leave:
271 RESTORE_ALL __LC_RETURN_PSW,1 294 RESTORE_ALL __LC_RETURN_PSW,1
295sysc_done:
296
297#ifdef CONFIG_TRACE_IRQFLAGS
298 .align 8
299 .globl sysc_restore_trace_psw
300sysc_restore_trace_psw:
301 .long 0, sysc_restore_trace + 0x80000000
302#endif
272 303
273# 304#
274# recheck if there is more work to do 305# recheck if there is more work to do
275# 306#
276sysc_work_loop: 307sysc_work_loop:
277 tm __TI_flags+3(%r9),_TIF_WORK_SVC 308 tm __TI_flags+3(%r9),_TIF_WORK_SVC
278 bz BASED(sysc_leave) # there is no work to do 309 bz BASED(sysc_restore) # there is no work to do
279# 310#
280# One of the work bits is on. Find out which one. 311# One of the work bits is on. Find out which one.
281# 312#
@@ -290,8 +321,8 @@ sysc_work:
290 bo BASED(sysc_restart) 321 bo BASED(sysc_restart)
291 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP 322 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
292 bo BASED(sysc_singlestep) 323 bo BASED(sysc_singlestep)
293 LOCKDEP_SYS_EXIT 324 b BASED(sysc_restore)
294 b BASED(sysc_leave) 325sysc_work_done:
295 326
296# 327#
297# _TIF_NEED_RESCHED is set, call schedule 328# _TIF_NEED_RESCHED is set, call schedule
@@ -458,6 +489,7 @@ pgm_check_handler:
458pgm_no_vtime: 489pgm_no_vtime:
459#endif 490#endif
460 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 491 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
492 TRACE_IRQS_OFF
461 l %r3,__LC_PGM_ILC # load program interruption code 493 l %r3,__LC_PGM_ILC # load program interruption code
462 la %r8,0x7f 494 la %r8,0x7f
463 nr %r8,%r3 495 nr %r8,%r3
@@ -497,6 +529,7 @@ pgm_per_std:
497pgm_no_vtime2: 529pgm_no_vtime2:
498#endif 530#endif
499 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 531 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
532 TRACE_IRQS_OFF
500 l %r1,__TI_task(%r9) 533 l %r1,__TI_task(%r9)
501 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 534 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
502 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 535 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -517,15 +550,13 @@ pgm_svcper:
517 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 550 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
518 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 551 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
519#ifdef CONFIG_VIRT_CPU_ACCOUNTING 552#ifdef CONFIG_VIRT_CPU_ACCOUNTING
520 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
521 bz BASED(pgm_no_vtime3)
522 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 553 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
523 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 554 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
524 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 555 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
525pgm_no_vtime3:
526#endif 556#endif
527 lh %r7,0x8a # get svc number from lowcore 557 lh %r7,0x8a # get svc number from lowcore
528 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 558 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
559 TRACE_IRQS_OFF
529 l %r1,__TI_task(%r9) 560 l %r1,__TI_task(%r9)
530 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 561 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
531 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 562 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -542,7 +573,7 @@ kernel_per:
542 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check 573 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
543 la %r2,SP_PTREGS(%r15) # address of register-save area 574 la %r2,SP_PTREGS(%r15) # address of register-save area
544 l %r1,BASED(.Lhandle_per) # load adr. of per handler 575 l %r1,BASED(.Lhandle_per) # load adr. of per handler
545 la %r14,BASED(sysc_leave) # load adr. of system return 576 la %r14,BASED(sysc_restore)# load adr. of system return
546 br %r1 # branch to do_single_step 577 br %r1 # branch to do_single_step
547 578
548/* 579/*
@@ -569,26 +600,38 @@ io_no_vtime:
569 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 600 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
570 la %r2,SP_PTREGS(%r15) # address of register-save area 601 la %r2,SP_PTREGS(%r15) # address of register-save area
571 basr %r14,%r1 # branch to standard irq handler 602 basr %r14,%r1 # branch to standard irq handler
572 TRACE_IRQS_ON
573
574io_return: 603io_return:
575 tm SP_PSW+1(%r15),0x01 # returning to user ? 604 tm SP_PSW+1(%r15),0x01 # returning to user ?
576#ifdef CONFIG_PREEMPT 605#ifdef CONFIG_PREEMPT
577 bno BASED(io_preempt) # no -> check for preemptive scheduling 606 bno BASED(io_preempt) # no -> check for preemptive scheduling
578#else 607#else
579 bno BASED(io_leave) # no-> skip resched & signal 608 bno BASED(io_restore) # no-> skip resched & signal
580#endif 609#endif
581 tm __TI_flags+3(%r9),_TIF_WORK_INT 610 tm __TI_flags+3(%r9),_TIF_WORK_INT
582 bnz BASED(io_work) # there is work to do (signals etc.) 611 bnz BASED(io_work) # there is work to do (signals etc.)
612io_restore:
613#ifdef CONFIG_TRACE_IRQFLAGS
614 la %r1,BASED(io_restore_trace_psw)
615 lpsw 0(%r1)
616io_restore_trace:
617 TRACE_IRQS_CHECK
583 LOCKDEP_SYS_EXIT 618 LOCKDEP_SYS_EXIT
619#endif
584io_leave: 620io_leave:
585 RESTORE_ALL __LC_RETURN_PSW,0 621 RESTORE_ALL __LC_RETURN_PSW,0
586io_done: 622io_done:
587 623
624#ifdef CONFIG_TRACE_IRQFLAGS
625 .align 8
626 .globl io_restore_trace_psw
627io_restore_trace_psw:
628 .long 0, io_restore_trace + 0x80000000
629#endif
630
588#ifdef CONFIG_PREEMPT 631#ifdef CONFIG_PREEMPT
589io_preempt: 632io_preempt:
590 icm %r0,15,__TI_precount(%r9) 633 icm %r0,15,__TI_precount(%r9)
591 bnz BASED(io_leave) 634 bnz BASED(io_restore)
592 l %r1,SP_R15(%r15) 635 l %r1,SP_R15(%r15)
593 s %r1,BASED(.Lc_spsize) 636 s %r1,BASED(.Lc_spsize)
594 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 637 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -596,12 +639,14 @@ io_preempt:
596 lr %r15,%r1 639 lr %r15,%r1
597io_resume_loop: 640io_resume_loop:
598 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 641 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
599 bno BASED(io_leave) 642 bno BASED(io_restore)
600 mvc __TI_precount(4,%r9),BASED(.Lc_pactive) 643 mvc __TI_precount(4,%r9),BASED(.Lc_pactive)
644 TRACE_IRQS_ON
601 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 645 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
602 l %r1,BASED(.Lschedule) 646 l %r1,BASED(.Lschedule)
603 basr %r14,%r1 # call schedule 647 basr %r14,%r1 # call schedule
604 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 648 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
649 TRACE_IRQS_OFF
605 xc __TI_precount(4,%r9),__TI_precount(%r9) 650 xc __TI_precount(4,%r9),__TI_precount(%r9)
606 b BASED(io_resume_loop) 651 b BASED(io_resume_loop)
607#endif 652#endif
@@ -627,40 +672,42 @@ io_work_loop:
627 bo BASED(io_reschedule) 672 bo BASED(io_reschedule)
628 tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 673 tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
629 bnz BASED(io_sigpending) 674 bnz BASED(io_sigpending)
630 LOCKDEP_SYS_EXIT 675 b BASED(io_restore)
631 b BASED(io_leave) 676io_work_done:
632 677
633# 678#
634# _TIF_MCCK_PENDING is set, call handler 679# _TIF_MCCK_PENDING is set, call handler
635# 680#
636io_mcck_pending: 681io_mcck_pending:
637 TRACE_IRQS_OFF
638 l %r1,BASED(.Ls390_handle_mcck) 682 l %r1,BASED(.Ls390_handle_mcck)
639 basr %r14,%r1 # TIF bit will be cleared by handler 683 basr %r14,%r1 # TIF bit will be cleared by handler
640 TRACE_IRQS_ON
641 b BASED(io_work_loop) 684 b BASED(io_work_loop)
642 685
643# 686#
644# _TIF_NEED_RESCHED is set, call schedule 687# _TIF_NEED_RESCHED is set, call schedule
645# 688#
646io_reschedule: 689io_reschedule:
690 TRACE_IRQS_ON
647 l %r1,BASED(.Lschedule) 691 l %r1,BASED(.Lschedule)
648 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 692 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
649 basr %r14,%r1 # call scheduler 693 basr %r14,%r1 # call scheduler
650 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 694 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
695 TRACE_IRQS_OFF
651 tm __TI_flags+3(%r9),_TIF_WORK_INT 696 tm __TI_flags+3(%r9),_TIF_WORK_INT
652 bz BASED(io_leave) # there is no work to do 697 bz BASED(io_restore) # there is no work to do
653 b BASED(io_work_loop) 698 b BASED(io_work_loop)
654 699
655# 700#
656# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 701# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
657# 702#
658io_sigpending: 703io_sigpending:
704 TRACE_IRQS_ON
659 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 705 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
660 la %r2,SP_PTREGS(%r15) # load pt_regs 706 la %r2,SP_PTREGS(%r15) # load pt_regs
661 l %r1,BASED(.Ldo_signal) 707 l %r1,BASED(.Ldo_signal)
662 basr %r14,%r1 # call do_signal 708 basr %r14,%r1 # call do_signal
663 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 709 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
710 TRACE_IRQS_OFF
664 b BASED(io_work_loop) 711 b BASED(io_work_loop)
665 712
666/* 713/*
@@ -688,7 +735,6 @@ ext_no_vtime:
688 lh %r3,__LC_EXT_INT_CODE # get interruption code 735 lh %r3,__LC_EXT_INT_CODE # get interruption code
689 l %r1,BASED(.Ldo_extint) 736 l %r1,BASED(.Ldo_extint)
690 basr %r14,%r1 737 basr %r14,%r1
691 TRACE_IRQS_ON
692 b BASED(io_return) 738 b BASED(io_return)
693 739
694__critical_end: 740__critical_end:
@@ -853,15 +899,15 @@ cleanup_table_system_call:
853cleanup_table_sysc_return: 899cleanup_table_sysc_return:
854 .long sysc_return + 0x80000000, sysc_leave + 0x80000000 900 .long sysc_return + 0x80000000, sysc_leave + 0x80000000
855cleanup_table_sysc_leave: 901cleanup_table_sysc_leave:
856 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 902 .long sysc_leave + 0x80000000, sysc_done + 0x80000000
857cleanup_table_sysc_work_loop: 903cleanup_table_sysc_work_loop:
858 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 904 .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000
859cleanup_table_io_return: 905cleanup_table_io_return:
860 .long io_return + 0x80000000, io_leave + 0x80000000 906 .long io_return + 0x80000000, io_leave + 0x80000000
861cleanup_table_io_leave: 907cleanup_table_io_leave:
862 .long io_leave + 0x80000000, io_done + 0x80000000 908 .long io_leave + 0x80000000, io_done + 0x80000000
863cleanup_table_io_work_loop: 909cleanup_table_io_work_loop:
864 .long io_work_loop + 0x80000000, io_mcck_pending + 0x80000000 910 .long io_work_loop + 0x80000000, io_work_done + 0x80000000
865 911
866cleanup_critical: 912cleanup_critical:
867 clc 4(4,%r12),BASED(cleanup_table_system_call) 913 clc 4(4,%r12),BASED(cleanup_table_system_call)
@@ -930,8 +976,6 @@ cleanup_system_call:
930cleanup_vtime: 976cleanup_vtime:
931 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 977 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
932 bhe BASED(cleanup_stime) 978 bhe BASED(cleanup_stime)
933 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
934 bz BASED(cleanup_novtime)
935 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 979 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
936cleanup_stime: 980cleanup_stime:
937 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16) 981 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
@@ -939,7 +983,6 @@ cleanup_stime:
939 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 983 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
940cleanup_update: 984cleanup_update:
941 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 985 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
942cleanup_novtime:
943#endif 986#endif
944 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4) 987 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
945 la %r12,__LC_RETURN_PSW 988 la %r12,__LC_RETURN_PSW
@@ -978,10 +1021,10 @@ cleanup_sysc_leave:
9782: la %r12,__LC_RETURN_PSW 10212: la %r12,__LC_RETURN_PSW
979 br %r14 1022 br %r14
980cleanup_sysc_leave_insn: 1023cleanup_sysc_leave_insn:
1024 .long sysc_done - 4 + 0x80000000
981#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1025#ifdef CONFIG_VIRT_CPU_ACCOUNTING
982 .long sysc_leave + 14 + 0x80000000 1026 .long sysc_done - 8 + 0x80000000
983#endif 1027#endif
984 .long sysc_leave + 10 + 0x80000000
985 1028
986cleanup_io_return: 1029cleanup_io_return:
987 mvc __LC_RETURN_PSW(4),0(%r12) 1030 mvc __LC_RETURN_PSW(4),0(%r12)
@@ -1008,10 +1051,10 @@ cleanup_io_leave:
10082: la %r12,__LC_RETURN_PSW 10512: la %r12,__LC_RETURN_PSW
1009 br %r14 1052 br %r14
1010cleanup_io_leave_insn: 1053cleanup_io_leave_insn:
1054 .long io_done - 4 + 0x80000000
1011#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1055#ifdef CONFIG_VIRT_CPU_ACCOUNTING
1012 .long io_leave + 18 + 0x80000000 1056 .long io_done - 8 + 0x80000000
1013#endif 1057#endif
1014 .long io_leave + 14 + 0x80000000
1015 1058
1016/* 1059/*
1017 * Integer constants 1060 * Integer constants
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 05e26d1fdf40..e15c80efdd05 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -67,12 +67,28 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
67 brasl %r14,trace_hardirqs_off 67 brasl %r14,trace_hardirqs_off
68 .endm 68 .endm
69 69
70 .macro LOCKDEP_SYS_EXIT 70 .macro TRACE_IRQS_CHECK
71 brasl %r14,lockdep_sys_exit 71 tm SP_PSW(%r15),0x03 # irqs enabled?
72 jz 0f
73 brasl %r14,trace_hardirqs_on
74 j 1f
750: brasl %r14,trace_hardirqs_off
761:
72 .endm 77 .endm
73#else 78#else
74#define TRACE_IRQS_ON 79#define TRACE_IRQS_ON
75#define TRACE_IRQS_OFF 80#define TRACE_IRQS_OFF
81#define TRACE_IRQS_CHECK
82#endif
83
84#ifdef CONFIG_LOCKDEP
85 .macro LOCKDEP_SYS_EXIT
86 tm SP_PSW+1(%r15),0x01 # returning to user ?
87 jz 0f
88 brasl %r14,lockdep_sys_exit
890:
90 .endm
91#else
76#define LOCKDEP_SYS_EXIT 92#define LOCKDEP_SYS_EXIT
77#endif 93#endif
78 94
@@ -222,8 +238,6 @@ sysc_saveall:
222 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 238 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
223#ifdef CONFIG_VIRT_CPU_ACCOUNTING 239#ifdef CONFIG_VIRT_CPU_ACCOUNTING
224sysc_vtime: 240sysc_vtime:
225 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
226 jz sysc_do_svc
227 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 241 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
228sysc_stime: 242sysc_stime:
229 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 243 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -257,19 +271,34 @@ sysc_noemu:
257 271
258sysc_return: 272sysc_return:
259 tm SP_PSW+1(%r15),0x01 # returning to user ? 273 tm SP_PSW+1(%r15),0x01 # returning to user ?
260 jno sysc_leave 274 jno sysc_restore
261 tm __TI_flags+7(%r9),_TIF_WORK_SVC 275 tm __TI_flags+7(%r9),_TIF_WORK_SVC
262 jnz sysc_work # there is work to do (signals etc.) 276 jnz sysc_work # there is work to do (signals etc.)
277sysc_restore:
278#ifdef CONFIG_TRACE_IRQFLAGS
279 larl %r1,sysc_restore_trace_psw
280 lpswe 0(%r1)
281sysc_restore_trace:
282 TRACE_IRQS_CHECK
263 LOCKDEP_SYS_EXIT 283 LOCKDEP_SYS_EXIT
284#endif
264sysc_leave: 285sysc_leave:
265 RESTORE_ALL __LC_RETURN_PSW,1 286 RESTORE_ALL __LC_RETURN_PSW,1
287sysc_done:
288
289#ifdef CONFIG_TRACE_IRQFLAGS
290 .align 8
291 .globl sysc_restore_trace_psw
292sysc_restore_trace_psw:
293 .quad 0, sysc_restore_trace
294#endif
266 295
267# 296#
268# recheck if there is more work to do 297# recheck if there is more work to do
269# 298#
270sysc_work_loop: 299sysc_work_loop:
271 tm __TI_flags+7(%r9),_TIF_WORK_SVC 300 tm __TI_flags+7(%r9),_TIF_WORK_SVC
272 jz sysc_leave # there is no work to do 301 jz sysc_restore # there is no work to do
273# 302#
274# One of the work bits is on. Find out which one. 303# One of the work bits is on. Find out which one.
275# 304#
@@ -284,8 +313,8 @@ sysc_work:
284 jo sysc_restart 313 jo sysc_restart
285 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP 314 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
286 jo sysc_singlestep 315 jo sysc_singlestep
287 LOCKDEP_SYS_EXIT 316 j sysc_restore
288 j sysc_leave 317sysc_work_done:
289 318
290# 319#
291# _TIF_NEED_RESCHED is set, call schedule 320# _TIF_NEED_RESCHED is set, call schedule
@@ -445,6 +474,7 @@ pgm_check_handler:
445pgm_no_vtime: 474pgm_no_vtime:
446#endif 475#endif
447 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 476 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
477 TRACE_IRQS_OFF
448 lgf %r3,__LC_PGM_ILC # load program interruption code 478 lgf %r3,__LC_PGM_ILC # load program interruption code
449 lghi %r8,0x7f 479 lghi %r8,0x7f
450 ngr %r8,%r3 480 ngr %r8,%r3
@@ -484,6 +514,7 @@ pgm_per_std:
484pgm_no_vtime2: 514pgm_no_vtime2:
485#endif 515#endif
486 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 516 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
517 TRACE_IRQS_OFF
487 lg %r1,__TI_task(%r9) 518 lg %r1,__TI_task(%r9)
488 tm SP_PSW+1(%r15),0x01 # kernel per event ? 519 tm SP_PSW+1(%r15),0x01 # kernel per event ?
489 jz kernel_per 520 jz kernel_per
@@ -504,12 +535,9 @@ pgm_svcper:
504 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 535 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
505 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 536 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
506#ifdef CONFIG_VIRT_CPU_ACCOUNTING 537#ifdef CONFIG_VIRT_CPU_ACCOUNTING
507 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
508 jz pgm_no_vtime3
509 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 538 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
510 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 539 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
511 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 540 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
512pgm_no_vtime3:
513#endif 541#endif
514 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 542 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
515 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 543 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
@@ -529,7 +557,7 @@ kernel_per:
529 lhi %r0,__LC_PGM_OLD_PSW 557 lhi %r0,__LC_PGM_OLD_PSW
530 sth %r0,SP_TRAP(%r15) # set trap indication to pgm check 558 sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
531 la %r2,SP_PTREGS(%r15) # address of register-save area 559 la %r2,SP_PTREGS(%r15) # address of register-save area
532 larl %r14,sysc_leave # load adr. of system ret, no work 560 larl %r14,sysc_restore # load adr. of system ret, no work
533 jg do_single_step # branch to do_single_step 561 jg do_single_step # branch to do_single_step
534 562
535/* 563/*
@@ -554,26 +582,38 @@ io_no_vtime:
554 TRACE_IRQS_OFF 582 TRACE_IRQS_OFF
555 la %r2,SP_PTREGS(%r15) # address of register-save area 583 la %r2,SP_PTREGS(%r15) # address of register-save area
556 brasl %r14,do_IRQ # call standard irq handler 584 brasl %r14,do_IRQ # call standard irq handler
557 TRACE_IRQS_ON
558
559io_return: 585io_return:
560 tm SP_PSW+1(%r15),0x01 # returning to user ? 586 tm SP_PSW+1(%r15),0x01 # returning to user ?
561#ifdef CONFIG_PREEMPT 587#ifdef CONFIG_PREEMPT
562 jno io_preempt # no -> check for preemptive scheduling 588 jno io_preempt # no -> check for preemptive scheduling
563#else 589#else
564 jno io_leave # no-> skip resched & signal 590 jno io_restore # no-> skip resched & signal
565#endif 591#endif
566 tm __TI_flags+7(%r9),_TIF_WORK_INT 592 tm __TI_flags+7(%r9),_TIF_WORK_INT
567 jnz io_work # there is work to do (signals etc.) 593 jnz io_work # there is work to do (signals etc.)
594io_restore:
595#ifdef CONFIG_TRACE_IRQFLAGS
596 larl %r1,io_restore_trace_psw
597 lpswe 0(%r1)
598io_restore_trace:
599 TRACE_IRQS_CHECK
568 LOCKDEP_SYS_EXIT 600 LOCKDEP_SYS_EXIT
601#endif
569io_leave: 602io_leave:
570 RESTORE_ALL __LC_RETURN_PSW,0 603 RESTORE_ALL __LC_RETURN_PSW,0
571io_done: 604io_done:
572 605
606#ifdef CONFIG_TRACE_IRQFLAGS
607 .align 8
608 .globl io_restore_trace_psw
609io_restore_trace_psw:
610 .quad 0, io_restore_trace
611#endif
612
573#ifdef CONFIG_PREEMPT 613#ifdef CONFIG_PREEMPT
574io_preempt: 614io_preempt:
575 icm %r0,15,__TI_precount(%r9) 615 icm %r0,15,__TI_precount(%r9)
576 jnz io_leave 616 jnz io_restore
577 # switch to kernel stack 617 # switch to kernel stack
578 lg %r1,SP_R15(%r15) 618 lg %r1,SP_R15(%r15)
579 aghi %r1,-SP_SIZE 619 aghi %r1,-SP_SIZE
@@ -582,12 +622,14 @@ io_preempt:
582 lgr %r15,%r1 622 lgr %r15,%r1
583io_resume_loop: 623io_resume_loop:
584 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED 624 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
585 jno io_leave 625 jno io_restore
586 larl %r1,.Lc_pactive 626 larl %r1,.Lc_pactive
587 mvc __TI_precount(4,%r9),0(%r1) 627 mvc __TI_precount(4,%r9),0(%r1)
628 TRACE_IRQS_ON
588 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 629 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
589 brasl %r14,schedule # call schedule 630 brasl %r14,schedule # call schedule
590 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 631 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
632 TRACE_IRQS_OFF
591 xc __TI_precount(4,%r9),__TI_precount(%r9) 633 xc __TI_precount(4,%r9),__TI_precount(%r9)
592 j io_resume_loop 634 j io_resume_loop
593#endif 635#endif
@@ -613,37 +655,39 @@ io_work_loop:
613 jo io_reschedule 655 jo io_reschedule
614 tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 656 tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
615 jnz io_sigpending 657 jnz io_sigpending
616 LOCKDEP_SYS_EXIT 658 j io_restore
617 j io_leave 659io_work_done:
618 660
619# 661#
620# _TIF_MCCK_PENDING is set, call handler 662# _TIF_MCCK_PENDING is set, call handler
621# 663#
622io_mcck_pending: 664io_mcck_pending:
623 TRACE_IRQS_OFF
624 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler 665 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler
625 TRACE_IRQS_ON
626 j io_work_loop 666 j io_work_loop
627 667
628# 668#
629# _TIF_NEED_RESCHED is set, call schedule 669# _TIF_NEED_RESCHED is set, call schedule
630# 670#
631io_reschedule: 671io_reschedule:
672 TRACE_IRQS_ON
632 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 673 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
633 brasl %r14,schedule # call scheduler 674 brasl %r14,schedule # call scheduler
634 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 675 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
676 TRACE_IRQS_OFF
635 tm __TI_flags+7(%r9),_TIF_WORK_INT 677 tm __TI_flags+7(%r9),_TIF_WORK_INT
636 jz io_leave # there is no work to do 678 jz io_restore # there is no work to do
637 j io_work_loop 679 j io_work_loop
638 680
639# 681#
640# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 682# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
641# 683#
642io_sigpending: 684io_sigpending:
685 TRACE_IRQS_ON
643 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 686 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
644 la %r2,SP_PTREGS(%r15) # load pt_regs 687 la %r2,SP_PTREGS(%r15) # load pt_regs
645 brasl %r14,do_signal # call do_signal 688 brasl %r14,do_signal # call do_signal
646 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 689 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
690 TRACE_IRQS_OFF
647 j io_work_loop 691 j io_work_loop
648 692
649/* 693/*
@@ -669,7 +713,6 @@ ext_no_vtime:
669 la %r2,SP_PTREGS(%r15) # address of register-save area 713 la %r2,SP_PTREGS(%r15) # address of register-save area
670 llgh %r3,__LC_EXT_INT_CODE # get interruption code 714 llgh %r3,__LC_EXT_INT_CODE # get interruption code
671 brasl %r14,do_extint 715 brasl %r14,do_extint
672 TRACE_IRQS_ON
673 j io_return 716 j io_return
674 717
675__critical_end: 718__critical_end:
@@ -824,15 +867,15 @@ cleanup_table_system_call:
824cleanup_table_sysc_return: 867cleanup_table_sysc_return:
825 .quad sysc_return, sysc_leave 868 .quad sysc_return, sysc_leave
826cleanup_table_sysc_leave: 869cleanup_table_sysc_leave:
827 .quad sysc_leave, sysc_work_loop 870 .quad sysc_leave, sysc_done
828cleanup_table_sysc_work_loop: 871cleanup_table_sysc_work_loop:
829 .quad sysc_work_loop, sysc_reschedule 872 .quad sysc_work_loop, sysc_work_done
830cleanup_table_io_return: 873cleanup_table_io_return:
831 .quad io_return, io_leave 874 .quad io_return, io_leave
832cleanup_table_io_leave: 875cleanup_table_io_leave:
833 .quad io_leave, io_done 876 .quad io_leave, io_done
834cleanup_table_io_work_loop: 877cleanup_table_io_work_loop:
835 .quad io_work_loop, io_mcck_pending 878 .quad io_work_loop, io_work_done
836 879
837cleanup_critical: 880cleanup_critical:
838 clc 8(8,%r12),BASED(cleanup_table_system_call) 881 clc 8(8,%r12),BASED(cleanup_table_system_call)
@@ -901,8 +944,6 @@ cleanup_system_call:
901cleanup_vtime: 944cleanup_vtime:
902 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 945 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
903 jhe cleanup_stime 946 jhe cleanup_stime
904 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
905 jz cleanup_novtime
906 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 947 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
907cleanup_stime: 948cleanup_stime:
908 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32) 949 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32)
@@ -910,7 +951,6 @@ cleanup_stime:
910 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 951 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
911cleanup_update: 952cleanup_update:
912 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 953 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
913cleanup_novtime:
914#endif 954#endif
915 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) 955 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
916 la %r12,__LC_RETURN_PSW 956 la %r12,__LC_RETURN_PSW
@@ -949,10 +989,10 @@ cleanup_sysc_leave:
9492: la %r12,__LC_RETURN_PSW 9892: la %r12,__LC_RETURN_PSW
950 br %r14 990 br %r14
951cleanup_sysc_leave_insn: 991cleanup_sysc_leave_insn:
992 .quad sysc_done - 4
952#ifdef CONFIG_VIRT_CPU_ACCOUNTING 993#ifdef CONFIG_VIRT_CPU_ACCOUNTING
953 .quad sysc_leave + 16 994 .quad sysc_done - 8
954#endif 995#endif
955 .quad sysc_leave + 12
956 996
957cleanup_io_return: 997cleanup_io_return:
958 mvc __LC_RETURN_PSW(8),0(%r12) 998 mvc __LC_RETURN_PSW(8),0(%r12)
@@ -979,10 +1019,10 @@ cleanup_io_leave:
9792: la %r12,__LC_RETURN_PSW 10192: la %r12,__LC_RETURN_PSW
980 br %r14 1020 br %r14
981cleanup_io_leave_insn: 1021cleanup_io_leave_insn:
1022 .quad io_done - 4
982#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1023#ifdef CONFIG_VIRT_CPU_ACCOUNTING
983 .quad io_leave + 20 1024 .quad io_done - 8
984#endif 1025#endif
985 .quad io_leave + 16
986 1026
987/* 1027/*
988 * Integer constants 1028 * Integer constants
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c4131a817412..50f8f1e3760e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -492,6 +492,10 @@ static void setup_addressing_mode(void)
492 printk("S390 address spaces switched, "); 492 printk("S390 address spaces switched, ");
493 set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY); 493 set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY);
494 } 494 }
495#ifdef CONFIG_TRACE_IRQFLAGS
496 sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
497 io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
498#endif
495} 499}
496 500
497static void __init 501static void __init
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index d866d3385556..44bda786eef7 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -388,6 +388,11 @@ extern void (*_machine_power_off)(void);
388 388
389#define arch_align_stack(x) (x) 389#define arch_align_stack(x) (x)
390 390
391#ifdef CONFIG_TRACE_IRQFLAGS
392extern psw_t sysc_restore_trace_psw;
393extern psw_t io_restore_trace_psw;
394#endif
395
391#endif /* __KERNEL__ */ 396#endif /* __KERNEL__ */
392 397
393#endif 398#endif