[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>
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S
index 96290cc..8cdb86e 100644
--- a/arch/s390/kernel/relocate_kernel64.S
+++ b/arch/s390/kernel/relocate_kernel64.S
@@ -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
-