path: root/arch/powerpc/kernel
diff options
authorJimi Xenidis <jimix@pobox.com>2012-12-03 17:05:47 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-01-10 17:00:39 +1100
commit96f013fe1b0904ee9059aa5105f7aa4959cd3914 (patch)
tree7ed6a997c91b48d09d8312c247df0eb350c0dfc4 /arch/powerpc/kernel
parentc7c360eedb8c1eea302a224a8c83d19a4e4cf608 (diff)
powerpc/kexec: Add kexec "hold" support for Book3e processors
Motivation: IBM Blue Gene/Q comes with some very strange firmware that I'm trying to get out of using in the kernel. So instead I spin all the threads in the boot wrapper (using the firmware) and have them enter the kexec stub, pre-translated at the virtual "linear" address, never touching firmware again. This works strategy works wonderfully, but I need the following patch in the kexec stub. I believe it should not effect Book3S and Book3E does not appear to be here yet so I'd love to get any criticisms up front. This patch adds two items: 1) Book3e requires that GPR4 survive the "hold" process, so we make sure that happens. 2) Book3e has no real mode, and the hold code exploits this. Since these processors ares always translated, we arrange for the kexeced threads to enter the hold code using the normal kernel linear mapping. Signed-off-by: Jimi Xenidis <jimix@pobox.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 1697a25ebe9..0886ae6dd5b 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -122,6 +122,8 @@ __secondary_hold:
/* Grab our physical cpu number */
mr r24,r3
+ /* stash r4 for book3e */
+ mr r25,r4
/* Tell the master cpu we're here */
/* Relocation is off & we are located at an address less */
@@ -129,16 +131,31 @@ __secondary_hold:
std r24,__secondary_hold_acknowledge-_stext(0)
+ li r26,0
+ tovirt(r26,r26)
/* All secondary cpus wait here until told to start. */
-100: ld r4,__secondary_hold_spinloop-_stext(0)
+100: ld r4,__secondary_hold_spinloop-_stext(r26)
cmpdi 0,r4,0
beq 100b
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
+ tovirt(r4,r4)
ld r4,0(r4) /* deref function descriptor */
mtctr r4
mr r3,r24
+ /*
+ * it may be the case that other platforms have r4 right to
+ * begin with, this gives us some safety in case it is not
+ */
+ mr r4,r25
li r4,0
/* Make sure that patched code is visible */