aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/head_64.S
diff options
context:
space:
mode:
authorMohan Kumar M <mohan@in.ibm.com>2008-10-21 17:38:10 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-22 15:01:22 +1100
commit54622f10a6aabb8bb2bdacf3dd070046f03dc246 (patch)
tree73eb5ad4eeb7174b8c0ae1904bbe80602c5e295d /arch/powerpc/kernel/head_64.S
parent4792adbac9eb41cea77a45ab76258ea10d411173 (diff)
powerpc: Support for relocatable kdump kernel
This adds relocatable kernel support for kdump. With this one can use the same regular kernel to capture the kdump. A signature (0xfeed1234) is passed in r6 from panic code to the next kernel through kexec_sequence and purgatory code. The signature is used to differentiate between kdump kernel and non-kdump kernels. The purgatory code compares the signature and sets the __kdump_flag in head_64.S. During the boot up, kernel code checks __kdump_flag and if it is set, the kernel will behave as relocatable kdump kernel. This kernel will boot at the address where it was loaded by kexec-tools ie. at the address reserved through crashkernel boot parameter. CONFIG_CRASH_DUMP depends on CONFIG_RELOCATABLE option to build kdump kernel as relocatable. So the same kernel can be used as production and kdump kernel. This patch incorporates the changes suggested by Paul Mackerras to avoid GOT use and to avoid two copies of the code. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Mohan Kumar M <mohan@in.ibm.com> Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r--arch/powerpc/kernel/head_64.S39
1 files changed, 33 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 84856bee33a..69489bd3210 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -97,6 +97,12 @@ __secondary_hold_spinloop:
__secondary_hold_acknowledge:
.llong 0x0
+ /* This flag is set by purgatory if we should be a kdump kernel. */
+ /* Do not move this variable as purgatory knows about it. */
+ .globl __kdump_flag
+__kdump_flag:
+ .llong 0x0
+
#ifdef CONFIG_PPC_ISERIES
/*
* At offset 0x20, there is a pointer to iSeries LPAR data.
@@ -1384,7 +1390,13 @@ _STATIC(__after_prom_start)
/* process relocations for the final address of the kernel */
lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
sldi r25,r25,32
- mr r3,r25
+#ifdef CONFIG_CRASH_DUMP
+ ld r7,__kdump_flag-_stext(r26)
+ cmpldi cr0,r7,1 /* kdump kernel ? - stay where we are */
+ bne 1f
+ add r25,r25,r26
+#endif
+1: mr r3,r25
bl .relocate
#endif
@@ -1398,11 +1410,26 @@ _STATIC(__after_prom_start)
li r3,0 /* target addr */
mr. r4,r26 /* In some cases the loader may */
beq 9f /* have already put us at zero */
- lis r5,(copy_to_here - _stext)@ha
- addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
li r6,0x100 /* Start offset, the first 0x100 */
/* bytes were copied earlier. */
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * Check if the kernel has to be running as relocatable kernel based on the
+ * variable __kdump_flag, if it is set the kernel is treated as relocatable
+ * kernel, otherwise it will be moved to PHYSICAL_START
+ */
+ ld r7,__kdump_flag-_stext(r26)
+ cmpldi cr0,r7,1
+ bne 3f
+
+ li r5,__end_interrupts - _stext /* just copy interrupts */
+ b 5f
+3:
+#endif
+ lis r5,(copy_to_here - _stext)@ha
+ addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
+
bl .copy_and_flush /* copy the first n bytes */
/* this includes the code being */
/* executed here. */
@@ -1411,15 +1438,15 @@ _STATIC(__after_prom_start)
mtctr r8
bctr
+p_end: .llong _end - _stext
+
4: /* Now copy the rest of the kernel up to _end */
addis r5,r26,(p_end - _stext)@ha
ld r5,(p_end - _stext)@l(r5) /* get _end */
- bl .copy_and_flush /* copy the rest */
+5: bl .copy_and_flush /* copy the rest */
9: b .start_here_multiplatform
-p_end: .llong _end - _stext
-
/*
* Copy routine used to copy the kernel to start at physical address 0
* and flush and invalidate the caches as needed.