[PATCH] s390: kexec fixes and improvements.
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Tue, 2 Aug 2005 04:11:33 +0000 (21:11 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 2 Aug 2005 04:37:59 +0000 (21:37 -0700)
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>
arch/s390/kernel/machine_kexec.c
arch/s390/kernel/relocate_kernel.S
arch/s390/kernel/relocate_kernel64.S
arch/s390/kernel/smp.c
arch/s390/kernel/traps.c

index 2721c3a..5aa71b0 100644 (file)
@@ -70,6 +70,8 @@ machine_kexec(struct kimage *image)
        for (;;);
 }
 
+extern void pfault_fini(void);
+
 static void
 kexec_halt_all_cpus(void *kernel_image)
 {
@@ -78,6 +80,11 @@ kexec_halt_all_cpus(void *kernel_image)
        struct kimage *image;
        relocate_kernel_t data_mover;
 
+#ifdef CONFIG_PFAULT
+       if (MACHINE_IS_VM)
+               pfault_fini();
+#endif
+
        if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
                signal_processor(smp_processor_id(), sigp_stop);
 
index d5e4a62..2a25ec7 100644 (file)
@@ -4,6 +4,7 @@
  * (C) Copyright IBM Corp. 2005
  *
  * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *           Heiko Carstens <heiko.carstens@de.ibm.com>
  *
  */
 
        relocate_kernel:
                basr    %r13,0          #base address
        .base:
-               spx     zero64-.base(%r13)      #absolute addressing mode
                stnsm   sys_msk-.base(%r13),0xf8        #disable DAT and IRQ (external)
+               spx     zero64-.base(%r13)      #absolute addressing mode
+               stctl   %c0,%c15,ctlregs-.base(%r13)
+               stm     %r0,%r15,gprregs-.base(%r13)
+               la      %r1,load_psw-.base(%r13)
+               mvc     0(8,%r0),0(%r1)
+               la      %r0,.back-.base(%r13)
+               st      %r0,4(%r0)
+               oi      4(%r0),0x80
+               mvc     0x68(8,%r0),0(%r1)
+               la      %r0,.back_pgm-.base(%r13)
+               st      %r0,0x6c(%r0)
+               oi      0x6c(%r0),0x80
+               lhi     %r0,0
+               diag    %r0,%r0,0x308
+       .back:
+               basr    %r13,0
+       .back_base:
+               oi      have_diag308-.back_base(%r13),0x01
+               lctl    %c0,%c15,ctlregs-.back_base(%r13)
+               lm      %r0,%r15,gprregs-.back_base(%r13)
+               j       .start_reloc
+       .back_pgm:
+               lm      %r0,%r15,gprregs-.base(%r13)
+       .start_reloc:
                lhi     %r10,-1         #preparing the mask
                sll     %r10,12         #shift it such that it becomes 0xf000
        .top:
                o       %r3,4(%r4)      #or load address into psw
                st      %r3,4(%r4)
                mvc     0(8,%r0),0(%r4) #copy psw to absolute address 0
+               tm      have_diag308-.base(%r13),0x01
+               jno     .no_diag308
+               diag    %r0,%r0,0x308
+       .no_diag308:
                sr      %r1,%r1         #clear %r1
                sr      %r2,%r2         #clear %r2
                sigp    %r1,%r2,0x12    #set cpuid to zero
                .long   0x00080000,0x80000000
        sys_msk:
                .quad   0
+       ctlregs:
+               .rept   16
+               .long   0
+               .endr
+       gprregs:
+               .rept   16
+               .long   0
+               .endr
+       have_diag308:
+               .byte   0
+               .align  8
        relocate_kernel_end:
        .globl  relocate_kernel_len
        relocate_kernel_len:
index 96290cc..8cdb86e 100644 (file)
@@ -4,6 +4,7 @@
  * (C) Copyright IBM Corp. 2005
  *
  * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *           Heiko Carstens <heiko.carstens@de.ibm.com>
  *
  */
 
        relocate_kernel:
                basr    %r13,0          #base address
        .base:
+               stnsm   sys_msk-.base(%r13),0xf8        #disable DAT and IRQs
                spx     zero64-.base(%r13)      #absolute addressing mode
-               stnsm   sys_msk-.base(%r13),0xf8        #disable DAT and IRQ (external)
+               stctg   %c0,%c15,ctlregs-.base(%r13)
+               stmg    %r0,%r15,gprregs-.base(%r13)
+               lghi    %r0,3
+               sllg    %r0,%r0,31
+               stg     %r0,0x1d0(%r0)
+               la      %r0,.back_pgm-.base(%r13)
+               stg     %r0,0x1d8(%r0)
+               la      %r1,load_psw-.base(%r13)
+               mvc     0(8,%r0),0(%r1)
+               la      %r0,.back-.base(%r13)
+               st      %r0,4(%r0)
+               oi      4(%r0),0x80
+               lghi    %r0,0
+               diag    %r0,%r0,0x308
+       .back:
+               lhi     %r1,1           #mode 1 = esame
+               sigp    %r1,%r0,0x12    #switch to esame mode
+               sam64                   #switch to 64 bit addressing mode
+               basr    %r13,0
+       .back_base:
+               oi      have_diag308-.back_base(%r13),0x01
+               lctlg   %c0,%c15,ctlregs-.back_base(%r13)
+               lmg     %r0,%r15,gprregs-.back_base(%r13)
+               j       .top
+       .back_pgm:
+               lmg     %r0,%r15,gprregs-.base(%r13)
        .top:
                lghi    %r7,4096        #load PAGE_SIZE in r7
                lghi    %r9,4096        #load PAGE_SIZE in r9
                o       %r3,4(%r4)      #or load address into psw
                st      %r3,4(%r4)
                mvc     0(8,%r0),0(%r4) #copy psw to absolute address 0
+               tm      have_diag308-.base(%r13),0x01
+               jno     .no_diag308
+               diag    %r0,%r0,0x308
+       .no_diag308:
                sam31                   #31 bit mode
                sr      %r1,%r1         #erase register r1
                sr      %r2,%r2         #erase register r2
                .long   0x00080000,0x80000000
        sys_msk:
                .quad   0
+       ctlregs:
+               .rept   16
+               .quad   0
+               .endr
+       gprregs:
+               .rept   16
+               .quad   0
+               .endr
+       have_diag308:
+               .byte   0
+               .align  8
        relocate_kernel_end:
        .globl  relocate_kernel_len
        relocate_kernel_len:
                .quad   relocate_kernel_end - relocate_kernel
-
index da77f00..85222fe 100644 (file)
@@ -537,7 +537,8 @@ int __devinit start_secondary(void *cpuvoid)
 #endif
 #ifdef CONFIG_PFAULT
        /* Enable pfault pseudo page faults on this cpu. */
-       pfault_init();
+       if (MACHINE_IS_VM)
+               pfault_init();
 #endif
        /* Mark this cpu as online */
        cpu_set(smp_processor_id(), cpu_online_map);
@@ -690,7 +691,8 @@ __cpu_disable(void)
 
 #ifdef CONFIG_PFAULT
        /* Disable pfault pseudo page faults on this cpu. */
-       pfault_fini();
+       if (MACHINE_IS_VM)
+               pfault_fini();
 #endif
 
        /* disable all external interrupts */
index bc7b7be..6b8703e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
+#include <linux/reboot.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -675,6 +676,19 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
        panic("Corrupt kernel stack, can't continue.");
 }
 
+#ifndef CONFIG_ARCH_S390X
+static int
+pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+       if (MACHINE_IS_VM)
+               cpcmd("SET PAGEX OFF", NULL, 0, NULL);
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block pagex_reboot_notifier = {
+       .notifier_call = &pagex_reboot_event,
+};
+#endif
 
 /* init is done in lowcore.S and head.S */
 
@@ -735,6 +749,7 @@ void __init trap_init(void)
                                                    &ext_int_pfault);
 #endif
 #ifndef CONFIG_ARCH_S390X
+               register_reboot_notifier(&pagex_reboot_notifier);
                cpcmd("SET PAGEX ON", NULL, 0, NULL);
 #endif
        }