[PATCH] s390: kexec fixes and improvements.

Disable pseudo page fault handling before starting the new kernel and try
to use diag308 to reset the machine.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Heiko Carstens and committed by Linus Torvalds 5d3f229f 4374ae10

+109 -5
+7
arch/s390/kernel/machine_kexec.c
··· 70 70 for (;;); 71 71 } 72 72 73 + extern void pfault_fini(void); 74 + 73 75 static void 74 76 kexec_halt_all_cpus(void *kernel_image) 75 77 { ··· 79 77 int cpu; 80 78 struct kimage *image; 81 79 relocate_kernel_t data_mover; 80 + 81 + #ifdef CONFIG_PFAULT 82 + if (MACHINE_IS_VM) 83 + pfault_fini(); 84 + #endif 82 85 83 86 if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid)) 84 87 signal_processor(smp_processor_id(), sigp_stop);
+40 -1
arch/s390/kernel/relocate_kernel.S
··· 4 4 * (C) Copyright IBM Corp. 2005 5 5 * 6 6 * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> 7 + * Heiko Carstens <heiko.carstens@de.ibm.com> 7 8 * 8 9 */ 9 10 ··· 26 25 relocate_kernel: 27 26 basr %r13,0 #base address 28 27 .base: 29 - spx zero64-.base(%r13) #absolute addressing mode 30 28 stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) 29 + spx zero64-.base(%r13) #absolute addressing mode 30 + stctl %c0,%c15,ctlregs-.base(%r13) 31 + stm %r0,%r15,gprregs-.base(%r13) 32 + la %r1,load_psw-.base(%r13) 33 + mvc 0(8,%r0),0(%r1) 34 + la %r0,.back-.base(%r13) 35 + st %r0,4(%r0) 36 + oi 4(%r0),0x80 37 + mvc 0x68(8,%r0),0(%r1) 38 + la %r0,.back_pgm-.base(%r13) 39 + st %r0,0x6c(%r0) 40 + oi 0x6c(%r0),0x80 41 + lhi %r0,0 42 + diag %r0,%r0,0x308 43 + .back: 44 + basr %r13,0 45 + .back_base: 46 + oi have_diag308-.back_base(%r13),0x01 47 + lctl %c0,%c15,ctlregs-.back_base(%r13) 48 + lm %r0,%r15,gprregs-.back_base(%r13) 49 + j .start_reloc 50 + .back_pgm: 51 + lm %r0,%r15,gprregs-.base(%r13) 52 + .start_reloc: 31 53 lhi %r10,-1 #preparing the mask 32 54 sll %r10,12 #shift it such that it becomes 0xf000 33 55 .top: ··· 87 63 o %r3,4(%r4) #or load address into psw 88 64 st %r3,4(%r4) 89 65 mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 66 + tm have_diag308-.base(%r13),0x01 67 + jno .no_diag308 68 + diag %r0,%r0,0x308 69 + .no_diag308: 90 70 sr %r1,%r1 #clear %r1 91 71 sr %r2,%r2 #clear %r2 92 72 sigp %r1,%r2,0x12 #set cpuid to zero ··· 103 75 .long 0x00080000,0x80000000 104 76 sys_msk: 105 77 .quad 0 78 + ctlregs: 79 + .rept 16 80 + .long 0 81 + .endr 82 + gprregs: 83 + .rept 16 84 + .long 0 85 + .endr 86 + have_diag308: 87 + .byte 0 88 + .align 8 106 89 relocate_kernel_end: 107 90 .globl relocate_kernel_len 108 91 relocate_kernel_len:
+43 -2
arch/s390/kernel/relocate_kernel64.S
··· 4 4 * (C) Copyright IBM Corp. 2005 5 5 * 6 6 * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> 7 + * Heiko Carstens <heiko.carstens@de.ibm.com> 7 8 * 8 9 */ 9 10 ··· 27 26 relocate_kernel: 28 27 basr %r13,0 #base address 29 28 .base: 29 + stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQs 30 30 spx zero64-.base(%r13) #absolute addressing mode 31 - stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) 31 + stctg %c0,%c15,ctlregs-.base(%r13) 32 + stmg %r0,%r15,gprregs-.base(%r13) 33 + lghi %r0,3 34 + sllg %r0,%r0,31 35 + stg %r0,0x1d0(%r0) 36 + la %r0,.back_pgm-.base(%r13) 37 + stg %r0,0x1d8(%r0) 38 + la %r1,load_psw-.base(%r13) 39 + mvc 0(8,%r0),0(%r1) 40 + la %r0,.back-.base(%r13) 41 + st %r0,4(%r0) 42 + oi 4(%r0),0x80 43 + lghi %r0,0 44 + diag %r0,%r0,0x308 45 + .back: 46 + lhi %r1,1 #mode 1 = esame 47 + sigp %r1,%r0,0x12 #switch to esame mode 48 + sam64 #switch to 64 bit addressing mode 49 + basr %r13,0 50 + .back_base: 51 + oi have_diag308-.back_base(%r13),0x01 52 + lctlg %c0,%c15,ctlregs-.back_base(%r13) 53 + lmg %r0,%r15,gprregs-.back_base(%r13) 54 + j .top 55 + .back_pgm: 56 + lmg %r0,%r15,gprregs-.base(%r13) 32 57 .top: 33 58 lghi %r7,4096 #load PAGE_SIZE in r7 34 59 lghi %r9,4096 #load PAGE_SIZE in r9 ··· 89 62 o %r3,4(%r4) #or load address into psw 90 63 st %r3,4(%r4) 91 64 mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 65 + tm have_diag308-.base(%r13),0x01 66 + jno .no_diag308 67 + diag %r0,%r0,0x308 68 + .no_diag308: 92 69 sam31 #31 bit mode 93 70 sr %r1,%r1 #erase register r1 94 71 sr %r2,%r2 #erase register r2 ··· 106 75 .long 0x00080000,0x80000000 107 76 sys_msk: 108 77 .quad 0 78 + ctlregs: 79 + .rept 16 80 + .quad 0 81 + .endr 82 + gprregs: 83 + .rept 16 84 + .quad 0 85 + .endr 86 + have_diag308: 87 + .byte 0 88 + .align 8 109 89 relocate_kernel_end: 110 90 .globl relocate_kernel_len 111 91 relocate_kernel_len: 112 92 .quad relocate_kernel_end - relocate_kernel 113 -
+4 -2
arch/s390/kernel/smp.c
··· 537 537 #endif 538 538 #ifdef CONFIG_PFAULT 539 539 /* Enable pfault pseudo page faults on this cpu. */ 540 - pfault_init(); 540 + if (MACHINE_IS_VM) 541 + pfault_init(); 541 542 #endif 542 543 /* Mark this cpu as online */ 543 544 cpu_set(smp_processor_id(), cpu_online_map); ··· 691 690 692 691 #ifdef CONFIG_PFAULT 693 692 /* Disable pfault pseudo page faults on this cpu. */ 694 - pfault_fini(); 693 + if (MACHINE_IS_VM) 694 + pfault_fini(); 695 695 #endif 696 696 697 697 /* disable all external interrupts */
+15
arch/s390/kernel/traps.c
··· 29 29 #include <linux/delay.h> 30 30 #include <linux/module.h> 31 31 #include <linux/kallsyms.h> 32 + #include <linux/reboot.h> 32 33 33 34 #include <asm/system.h> 34 35 #include <asm/uaccess.h> ··· 676 675 panic("Corrupt kernel stack, can't continue."); 677 676 } 678 677 678 + #ifndef CONFIG_ARCH_S390X 679 + static int 680 + pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) 681 + { 682 + if (MACHINE_IS_VM) 683 + cpcmd("SET PAGEX OFF", NULL, 0, NULL); 684 + return NOTIFY_DONE; 685 + } 686 + 687 + static struct notifier_block pagex_reboot_notifier = { 688 + .notifier_call = &pagex_reboot_event, 689 + }; 690 + #endif 679 691 680 692 /* init is done in lowcore.S and head.S */ 681 693 ··· 749 735 &ext_int_pfault); 750 736 #endif 751 737 #ifndef CONFIG_ARCH_S390X 738 + register_reboot_notifier(&pagex_reboot_notifier); 752 739 cpcmd("SET PAGEX ON", NULL, 0, NULL); 753 740 #endif 754 741 }