aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/early.c2
-rw-r--r--arch/s390/kernel/entry.S120
-rw-r--r--arch/s390/kernel/entry64.S114
-rw-r--r--arch/s390/kernel/setup.c6
-rw-r--r--arch/s390/kernel/smp.c56
-rw-r--r--arch/s390/kernel/traps.c1
6 files changed, 166 insertions, 133 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 8bf4ae1150be..1b3af7dab816 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -200,7 +200,7 @@ static noinline __init void find_memory_chunks(unsigned long memsize)
200 cc = __tprot(addr); 200 cc = __tprot(addr);
201 while (cc == old_cc) { 201 while (cc == old_cc) {
202 addr += CHUNK_INCR; 202 addr += CHUNK_INCR;
203 if (addr >= memsize) 203 if (memsize && addr >= memsize)
204 break; 204 break;
205#ifndef CONFIG_64BIT 205#ifndef CONFIG_64BIT
206 if (addr == ADDR2G) 206 if (addr == ADDR2G)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 139ca153d5cc..b2b2edc40eb1 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,14 +639,10 @@ 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 l %r1,BASED(.Lpreempt_schedule_irq)
601 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 644 la %r14,BASED(io_resume_loop)
602 l %r1,BASED(.Lschedule) 645 br %r1 # call schedule
603 basr %r14,%r1 # call schedule
604 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
605 xc __TI_precount(4,%r9),__TI_precount(%r9)
606 b BASED(io_resume_loop)
607#endif 646#endif
608 647
609# 648#
@@ -627,40 +666,42 @@ io_work_loop:
627 bo BASED(io_reschedule) 666 bo BASED(io_reschedule)
628 tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 667 tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
629 bnz BASED(io_sigpending) 668 bnz BASED(io_sigpending)
630 LOCKDEP_SYS_EXIT 669 b BASED(io_restore)
631 b BASED(io_leave) 670io_work_done:
632 671
633# 672#
634# _TIF_MCCK_PENDING is set, call handler 673# _TIF_MCCK_PENDING is set, call handler
635# 674#
636io_mcck_pending: 675io_mcck_pending:
637 TRACE_IRQS_OFF
638 l %r1,BASED(.Ls390_handle_mcck) 676 l %r1,BASED(.Ls390_handle_mcck)
639 basr %r14,%r1 # TIF bit will be cleared by handler 677 basr %r14,%r1 # TIF bit will be cleared by handler
640 TRACE_IRQS_ON
641 b BASED(io_work_loop) 678 b BASED(io_work_loop)
642 679
643# 680#
644# _TIF_NEED_RESCHED is set, call schedule 681# _TIF_NEED_RESCHED is set, call schedule
645# 682#
646io_reschedule: 683io_reschedule:
684 TRACE_IRQS_ON
647 l %r1,BASED(.Lschedule) 685 l %r1,BASED(.Lschedule)
648 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 686 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
649 basr %r14,%r1 # call scheduler 687 basr %r14,%r1 # call scheduler
650 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 688 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
689 TRACE_IRQS_OFF
651 tm __TI_flags+3(%r9),_TIF_WORK_INT 690 tm __TI_flags+3(%r9),_TIF_WORK_INT
652 bz BASED(io_leave) # there is no work to do 691 bz BASED(io_restore) # there is no work to do
653 b BASED(io_work_loop) 692 b BASED(io_work_loop)
654 693
655# 694#
656# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 695# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
657# 696#
658io_sigpending: 697io_sigpending:
698 TRACE_IRQS_ON
659 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 699 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
660 la %r2,SP_PTREGS(%r15) # load pt_regs 700 la %r2,SP_PTREGS(%r15) # load pt_regs
661 l %r1,BASED(.Ldo_signal) 701 l %r1,BASED(.Ldo_signal)
662 basr %r14,%r1 # call do_signal 702 basr %r14,%r1 # call do_signal
663 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 703 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
704 TRACE_IRQS_OFF
664 b BASED(io_work_loop) 705 b BASED(io_work_loop)
665 706
666/* 707/*
@@ -688,7 +729,6 @@ ext_no_vtime:
688 lh %r3,__LC_EXT_INT_CODE # get interruption code 729 lh %r3,__LC_EXT_INT_CODE # get interruption code
689 l %r1,BASED(.Ldo_extint) 730 l %r1,BASED(.Ldo_extint)
690 basr %r14,%r1 731 basr %r14,%r1
691 TRACE_IRQS_ON
692 b BASED(io_return) 732 b BASED(io_return)
693 733
694__critical_end: 734__critical_end:
@@ -853,15 +893,15 @@ cleanup_table_system_call:
853cleanup_table_sysc_return: 893cleanup_table_sysc_return:
854 .long sysc_return + 0x80000000, sysc_leave + 0x80000000 894 .long sysc_return + 0x80000000, sysc_leave + 0x80000000
855cleanup_table_sysc_leave: 895cleanup_table_sysc_leave:
856 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 896 .long sysc_leave + 0x80000000, sysc_done + 0x80000000
857cleanup_table_sysc_work_loop: 897cleanup_table_sysc_work_loop:
858 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 898 .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000
859cleanup_table_io_return: 899cleanup_table_io_return:
860 .long io_return + 0x80000000, io_leave + 0x80000000 900 .long io_return + 0x80000000, io_leave + 0x80000000
861cleanup_table_io_leave: 901cleanup_table_io_leave:
862 .long io_leave + 0x80000000, io_done + 0x80000000 902 .long io_leave + 0x80000000, io_done + 0x80000000
863cleanup_table_io_work_loop: 903cleanup_table_io_work_loop:
864 .long io_work_loop + 0x80000000, io_mcck_pending + 0x80000000 904 .long io_work_loop + 0x80000000, io_work_done + 0x80000000
865 905
866cleanup_critical: 906cleanup_critical:
867 clc 4(4,%r12),BASED(cleanup_table_system_call) 907 clc 4(4,%r12),BASED(cleanup_table_system_call)
@@ -930,8 +970,6 @@ cleanup_system_call:
930cleanup_vtime: 970cleanup_vtime:
931 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 971 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
932 bhe BASED(cleanup_stime) 972 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 973 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
936cleanup_stime: 974cleanup_stime:
937 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16) 975 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
@@ -939,7 +977,6 @@ cleanup_stime:
939 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 977 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
940cleanup_update: 978cleanup_update:
941 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 979 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
942cleanup_novtime:
943#endif 980#endif
944 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4) 981 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
945 la %r12,__LC_RETURN_PSW 982 la %r12,__LC_RETURN_PSW
@@ -978,10 +1015,10 @@ cleanup_sysc_leave:
9782: la %r12,__LC_RETURN_PSW 10152: la %r12,__LC_RETURN_PSW
979 br %r14 1016 br %r14
980cleanup_sysc_leave_insn: 1017cleanup_sysc_leave_insn:
1018 .long sysc_done - 4 + 0x80000000
981#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1019#ifdef CONFIG_VIRT_CPU_ACCOUNTING
982 .long sysc_leave + 14 + 0x80000000 1020 .long sysc_done - 8 + 0x80000000
983#endif 1021#endif
984 .long sysc_leave + 10 + 0x80000000
985 1022
986cleanup_io_return: 1023cleanup_io_return:
987 mvc __LC_RETURN_PSW(4),0(%r12) 1024 mvc __LC_RETURN_PSW(4),0(%r12)
@@ -1008,10 +1045,10 @@ cleanup_io_leave:
10082: la %r12,__LC_RETURN_PSW 10452: la %r12,__LC_RETURN_PSW
1009 br %r14 1046 br %r14
1010cleanup_io_leave_insn: 1047cleanup_io_leave_insn:
1048 .long io_done - 4 + 0x80000000
1011#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1049#ifdef CONFIG_VIRT_CPU_ACCOUNTING
1012 .long io_leave + 18 + 0x80000000 1050 .long io_done - 8 + 0x80000000
1013#endif 1051#endif
1014 .long io_leave + 14 + 0x80000000
1015 1052
1016/* 1053/*
1017 * Integer constants 1054 * Integer constants
@@ -1019,7 +1056,6 @@ cleanup_io_leave_insn:
1019 .align 4 1056 .align 4
1020.Lc_spsize: .long SP_SIZE 1057.Lc_spsize: .long SP_SIZE
1021.Lc_overhead: .long STACK_FRAME_OVERHEAD 1058.Lc_overhead: .long STACK_FRAME_OVERHEAD
1022.Lc_pactive: .long PREEMPT_ACTIVE
1023.Lnr_syscalls: .long NR_syscalls 1059.Lnr_syscalls: .long NR_syscalls
1024.L0x018: .short 0x018 1060.L0x018: .short 0x018
1025.L0x020: .short 0x020 1061.L0x020: .short 0x020
@@ -1043,6 +1079,8 @@ cleanup_io_leave_insn:
1043.Lexecve_tail: .long execve_tail 1079.Lexecve_tail: .long execve_tail
1044.Ljump_table: .long pgm_check_table 1080.Ljump_table: .long pgm_check_table
1045.Lschedule: .long schedule 1081.Lschedule: .long schedule
1082.Lpreempt_schedule_irq:
1083 .long preempt_schedule_irq
1046.Ltrace: .long syscall_trace 1084.Ltrace: .long syscall_trace
1047.Lschedtail: .long schedule_tail 1085.Lschedtail: .long schedule_tail
1048.Lsysc_table: .long sys_call_table 1086.Lsysc_table: .long sys_call_table
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 05e26d1fdf40..a3e47b893f07 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,14 +622,9 @@ 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 %r14,io_resume_loop
587 mvc __TI_precount(4,%r9),0(%r1) 627 jg preempt_schedule_irq
588 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
589 brasl %r14,schedule # call schedule
590 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
591 xc __TI_precount(4,%r9),__TI_precount(%r9)
592 j io_resume_loop
593#endif 628#endif
594 629
595# 630#
@@ -613,37 +648,39 @@ io_work_loop:
613 jo io_reschedule 648 jo io_reschedule
614 tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 649 tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
615 jnz io_sigpending 650 jnz io_sigpending
616 LOCKDEP_SYS_EXIT 651 j io_restore
617 j io_leave 652io_work_done:
618 653
619# 654#
620# _TIF_MCCK_PENDING is set, call handler 655# _TIF_MCCK_PENDING is set, call handler
621# 656#
622io_mcck_pending: 657io_mcck_pending:
623 TRACE_IRQS_OFF
624 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler 658 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler
625 TRACE_IRQS_ON
626 j io_work_loop 659 j io_work_loop
627 660
628# 661#
629# _TIF_NEED_RESCHED is set, call schedule 662# _TIF_NEED_RESCHED is set, call schedule
630# 663#
631io_reschedule: 664io_reschedule:
665 TRACE_IRQS_ON
632 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 666 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
633 brasl %r14,schedule # call scheduler 667 brasl %r14,schedule # call scheduler
634 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 668 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
669 TRACE_IRQS_OFF
635 tm __TI_flags+7(%r9),_TIF_WORK_INT 670 tm __TI_flags+7(%r9),_TIF_WORK_INT
636 jz io_leave # there is no work to do 671 jz io_restore # there is no work to do
637 j io_work_loop 672 j io_work_loop
638 673
639# 674#
640# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 675# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
641# 676#
642io_sigpending: 677io_sigpending:
678 TRACE_IRQS_ON
643 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 679 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
644 la %r2,SP_PTREGS(%r15) # load pt_regs 680 la %r2,SP_PTREGS(%r15) # load pt_regs
645 brasl %r14,do_signal # call do_signal 681 brasl %r14,do_signal # call do_signal
646 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 682 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
683 TRACE_IRQS_OFF
647 j io_work_loop 684 j io_work_loop
648 685
649/* 686/*
@@ -669,7 +706,6 @@ ext_no_vtime:
669 la %r2,SP_PTREGS(%r15) # address of register-save area 706 la %r2,SP_PTREGS(%r15) # address of register-save area
670 llgh %r3,__LC_EXT_INT_CODE # get interruption code 707 llgh %r3,__LC_EXT_INT_CODE # get interruption code
671 brasl %r14,do_extint 708 brasl %r14,do_extint
672 TRACE_IRQS_ON
673 j io_return 709 j io_return
674 710
675__critical_end: 711__critical_end:
@@ -824,15 +860,15 @@ cleanup_table_system_call:
824cleanup_table_sysc_return: 860cleanup_table_sysc_return:
825 .quad sysc_return, sysc_leave 861 .quad sysc_return, sysc_leave
826cleanup_table_sysc_leave: 862cleanup_table_sysc_leave:
827 .quad sysc_leave, sysc_work_loop 863 .quad sysc_leave, sysc_done
828cleanup_table_sysc_work_loop: 864cleanup_table_sysc_work_loop:
829 .quad sysc_work_loop, sysc_reschedule 865 .quad sysc_work_loop, sysc_work_done
830cleanup_table_io_return: 866cleanup_table_io_return:
831 .quad io_return, io_leave 867 .quad io_return, io_leave
832cleanup_table_io_leave: 868cleanup_table_io_leave:
833 .quad io_leave, io_done 869 .quad io_leave, io_done
834cleanup_table_io_work_loop: 870cleanup_table_io_work_loop:
835 .quad io_work_loop, io_mcck_pending 871 .quad io_work_loop, io_work_done
836 872
837cleanup_critical: 873cleanup_critical:
838 clc 8(8,%r12),BASED(cleanup_table_system_call) 874 clc 8(8,%r12),BASED(cleanup_table_system_call)
@@ -901,8 +937,6 @@ cleanup_system_call:
901cleanup_vtime: 937cleanup_vtime:
902 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 938 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
903 jhe cleanup_stime 939 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 940 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
907cleanup_stime: 941cleanup_stime:
908 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32) 942 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32)
@@ -910,7 +944,6 @@ cleanup_stime:
910 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 944 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
911cleanup_update: 945cleanup_update:
912 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 946 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
913cleanup_novtime:
914#endif 947#endif
915 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) 948 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
916 la %r12,__LC_RETURN_PSW 949 la %r12,__LC_RETURN_PSW
@@ -949,10 +982,10 @@ cleanup_sysc_leave:
9492: la %r12,__LC_RETURN_PSW 9822: la %r12,__LC_RETURN_PSW
950 br %r14 983 br %r14
951cleanup_sysc_leave_insn: 984cleanup_sysc_leave_insn:
985 .quad sysc_done - 4
952#ifdef CONFIG_VIRT_CPU_ACCOUNTING 986#ifdef CONFIG_VIRT_CPU_ACCOUNTING
953 .quad sysc_leave + 16 987 .quad sysc_done - 8
954#endif 988#endif
955 .quad sysc_leave + 12
956 989
957cleanup_io_return: 990cleanup_io_return:
958 mvc __LC_RETURN_PSW(8),0(%r12) 991 mvc __LC_RETURN_PSW(8),0(%r12)
@@ -979,17 +1012,16 @@ cleanup_io_leave:
9792: la %r12,__LC_RETURN_PSW 10122: la %r12,__LC_RETURN_PSW
980 br %r14 1013 br %r14
981cleanup_io_leave_insn: 1014cleanup_io_leave_insn:
1015 .quad io_done - 4
982#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1016#ifdef CONFIG_VIRT_CPU_ACCOUNTING
983 .quad io_leave + 20 1017 .quad io_done - 8
984#endif 1018#endif
985 .quad io_leave + 16
986 1019
987/* 1020/*
988 * Integer constants 1021 * Integer constants
989 */ 1022 */
990 .align 4 1023 .align 4
991.Lconst: 1024.Lconst:
992.Lc_pactive: .long PREEMPT_ACTIVE
993.Lnr_syscalls: .long NR_syscalls 1025.Lnr_syscalls: .long NR_syscalls
994.L0x0130: .short 0x130 1026.L0x0130: .short 0x130
995.L0x0140: .short 0x140 1027.L0x0140: .short 0x140
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 7e1bfb984064..50f8f1e3760e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -347,7 +347,7 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
347 347
348void machine_restart(char *command) 348void machine_restart(char *command)
349{ 349{
350 if (!in_interrupt() || oops_in_progress) 350 if ((!in_interrupt() && !in_atomic()) || oops_in_progress)
351 /* 351 /*
352 * Only unblank the console if we are called in enabled 352 * Only unblank the console if we are called in enabled
353 * context or a bust_spinlocks cleared the way for us. 353 * context or a bust_spinlocks cleared the way for us.
@@ -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/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index b05ae8584258..264ea906db4c 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -193,72 +193,30 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
193} 193}
194EXPORT_SYMBOL(smp_call_function_single); 194EXPORT_SYMBOL(smp_call_function_single);
195 195
196static void do_send_stop(void) 196void smp_send_stop(void)
197{ 197{
198 int cpu, rc; 198 int cpu, rc;
199 199
200 /* stop all processors */ 200 /* Disable all interrupts/machine checks */
201 for_each_online_cpu(cpu) { 201 __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
202 if (cpu == smp_processor_id())
203 continue;
204 do {
205 rc = signal_processor(cpu, sigp_stop);
206 } while (rc == sigp_busy);
207 }
208}
209 202
210static void do_store_status(void) 203 /* write magic number to zero page (absolute 0) */
211{ 204 lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
212 int cpu, rc;
213 205
214 /* store status of all processors in their lowcores (real 0) */ 206 /* stop all processors */
215 for_each_online_cpu(cpu) { 207 for_each_online_cpu(cpu) {
216 if (cpu == smp_processor_id()) 208 if (cpu == smp_processor_id())
217 continue; 209 continue;
218 do { 210 do {
219 rc = signal_processor_p( 211 rc = signal_processor(cpu, sigp_stop);
220 (__u32)(unsigned long) lowcore_ptr[cpu], cpu,
221 sigp_store_status_at_address);
222 } while (rc == sigp_busy); 212 } while (rc == sigp_busy);
223 }
224}
225 213
226static void do_wait_for_stop(void)
227{
228 int cpu;
229
230 /* Wait for all other cpus to enter stopped state */
231 for_each_online_cpu(cpu) {
232 if (cpu == smp_processor_id())
233 continue;
234 while (!smp_cpu_not_running(cpu)) 214 while (!smp_cpu_not_running(cpu))
235 cpu_relax(); 215 cpu_relax();
236 } 216 }
237} 217}
238 218
239/* 219/*
240 * this function sends a 'stop' sigp to all other CPUs in the system.
241 * it goes straight through.
242 */
243void smp_send_stop(void)
244{
245 /* Disable all interrupts/machine checks */
246 __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
247
248 /* write magic number to zero page (absolute 0) */
249 lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
250
251 /* stop other processors. */
252 do_send_stop();
253
254 /* wait until other processors are stopped */
255 do_wait_for_stop();
256
257 /* store status of other processors. */
258 do_store_status();
259}
260
261/*
262 * Reboot, halt and power_off routines for SMP. 220 * Reboot, halt and power_off routines for SMP.
263 */ 221 */
264void machine_restart_smp(char *__unused) 222void machine_restart_smp(char *__unused)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 8ec9def83ccb..8ed16a83fba7 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -260,6 +260,7 @@ void die(const char * str, struct pt_regs * regs, long err)
260 bust_spinlocks(1); 260 bust_spinlocks(1);
261 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 261 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
262 print_modules(); 262 print_modules();
263 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
263 show_regs(regs); 264 show_regs(regs);
264 bust_spinlocks(0); 265 bust_spinlocks(0);
265 add_taint(TAINT_DIE); 266 add_taint(TAINT_DIE);