Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d3f229f authored by Heiko Carstens's avatar Heiko Carstens Committed by Linus Torvalds
Browse files

[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: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4374ae10
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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);

+40 −1
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * (C) Copyright IBM Corp. 2005
 *
 * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
 *	      Heiko Carstens <heiko.carstens@de.ibm.com>
 *
 */

@@ -25,8 +26,31 @@
	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:
@@ -63,6 +87,10 @@
		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
@@ -75,6 +103,17 @@
		.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:
+43 −2
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * (C) Copyright IBM Corp. 2005
 *
 * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
 *	      Heiko Carstens <heiko.carstens@de.ibm.com>
 *
 */

@@ -26,8 +27,34 @@
	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
@@ -62,6 +89,10 @@
		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
@@ -75,8 +106,18 @@
		.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
+4 −2
Original line number Diff line number Diff line
@@ -537,6 +537,7 @@ int __devinit start_secondary(void *cpuvoid)
#endif
#ifdef CONFIG_PFAULT
	/* Enable pfault pseudo page faults on this cpu. */
	if (MACHINE_IS_VM)
		pfault_init();
#endif
	/* Mark this cpu as online */
@@ -690,6 +691,7 @@ __cpu_disable(void)

#ifdef CONFIG_PFAULT
	/* Disable pfault pseudo page faults on this cpu. */
	if (MACHINE_IS_VM)
		pfault_fini();
#endif

+15 −0
Original line number Diff line number Diff line
@@ -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
	}