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

Commit 54622f10 authored by Mohan Kumar M's avatar Mohan Kumar M Committed by Benjamin Herrenschmidt
Browse files

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: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarMohan Kumar M <mohan@in.ibm.com>
Signed-off-by: default avatarMichael Ellerman <michael@ellerman.id.au>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 4792adba
Loading
Loading
Loading
Loading
+11 −3
Original line number Original line Diff line number Diff line
@@ -109,7 +109,8 @@ There are two possible methods of using Kdump.
2) Or use the system kernel binary itself as dump-capture kernel and there is
2) Or use the system kernel binary itself as dump-capture kernel and there is
   no need to build a separate dump-capture kernel. This is possible
   no need to build a separate dump-capture kernel. This is possible
   only with the architecutres which support a relocatable kernel. As
   only with the architecutres which support a relocatable kernel. As
   of today, i386, x86_64 and ia64 architectures support relocatable kernel.
   of today, i386, x86_64, ppc64 and ia64 architectures support relocatable
   kernel.


Building a relocatable kernel is advantageous from the point of view that
Building a relocatable kernel is advantageous from the point of view that
one does not have to build a second kernel for capturing the dump. But
one does not have to build a second kernel for capturing the dump. But
@@ -207,8 +208,15 @@ Dump-capture kernel config options (Arch Dependent, i386 and x86_64)
Dump-capture kernel config options (Arch Dependent, ppc64)
Dump-capture kernel config options (Arch Dependent, ppc64)
----------------------------------------------------------
----------------------------------------------------------


*  Make and install the kernel and its modules. DO NOT add this kernel
1) Enable "Build a kdump crash kernel" support under "Kernel" options:
   to the boot loader configuration files.

   CONFIG_CRASH_DUMP=y

2)   Enable "Build a relocatable kernel" support

   CONFIG_RELOCATABLE=y

   Make and install the kernel and its modules.


Dump-capture kernel config options (Arch Dependent, ia64)
Dump-capture kernel config options (Arch Dependent, ia64)
----------------------------------------------------------
----------------------------------------------------------
+3 −7
Original line number Original line Diff line number Diff line
@@ -323,13 +323,11 @@ config KEXEC


config CRASH_DUMP
config CRASH_DUMP
	bool "Build a kdump crash kernel"
	bool "Build a kdump crash kernel"
	depends on PPC_MULTIPLATFORM && PPC64
	depends on PPC_MULTIPLATFORM && PPC64 && RELOCATABLE
	help
	help
	  Build a kernel suitable for use as a kdump capture kernel.
	  Build a kernel suitable for use as a kdump capture kernel.
	  The kernel will be linked at a different address than normal, and
	  The same kernel binary can be used as production kernel and dump
	  so can only be used for Kdump.
	  capture kernel.

	  Don't change this unless you know what you are doing.


config PHYP_DUMP
config PHYP_DUMP
	bool "Hypervisor-assisted dump (EXPERIMENTAL)"
	bool "Hypervisor-assisted dump (EXPERIMENTAL)"
@@ -829,11 +827,9 @@ config PAGE_OFFSET
	default "0xc000000000000000"
	default "0xc000000000000000"
config KERNEL_START
config KERNEL_START
	hex
	hex
	default "0xc000000002000000" if CRASH_DUMP
	default "0xc000000000000000"
	default "0xc000000000000000"
config PHYSICAL_START
config PHYSICAL_START
	hex
	hex
	default "0x02000000" if CRASH_DUMP
	default "0x00000000"
	default "0x00000000"
endif
endif


+12 −5
Original line number Original line Diff line number Diff line
@@ -9,6 +9,12 @@
 * Reserve to the end of the FWNMI area, see head_64.S */
 * Reserve to the end of the FWNMI area, see head_64.S */
#define KDUMP_RESERVE_LIMIT	0x10000 /* 64K */
#define KDUMP_RESERVE_LIMIT	0x10000 /* 64K */


/*
 * Used to differentiate between relocatable kdump kernel and other
 * kernels
 */
#define KDUMP_SIGNATURE	0xfeed1234

#ifdef CONFIG_CRASH_DUMP
#ifdef CONFIG_CRASH_DUMP


#define KDUMP_TRAMPOLINE_START	0x0100
#define KDUMP_TRAMPOLINE_START	0x0100
@@ -19,17 +25,18 @@
#endif /* CONFIG_CRASH_DUMP */
#endif /* CONFIG_CRASH_DUMP */


#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__
#ifdef CONFIG_CRASH_DUMP


extern unsigned long __kdump_flag;

#if defined(CONFIG_CRASH_DUMP) && !defined(CONFIG_RELOCATABLE)
extern void reserve_kdump_trampoline(void);
extern void reserve_kdump_trampoline(void);
extern void setup_kdump_trampoline(void);
extern void setup_kdump_trampoline(void);

#else
#else /* !CONFIG_CRASH_DUMP */
/* !CRASH_DUMP || RELOCATABLE */

static inline void reserve_kdump_trampoline(void) { ; }
static inline void reserve_kdump_trampoline(void) { ; }
static inline void setup_kdump_trampoline(void) { ; }
static inline void setup_kdump_trampoline(void) { ; }
#endif


#endif /* CONFIG_CRASH_DUMP */
#endif /* __ASSEMBLY__ */
#endif /* __ASSEMBLY__ */


#endif /* __PPC64_KDUMP_H */
#endif /* __PPC64_KDUMP_H */
+2 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@
/* Stores the physical address of elf header of crash image. */
/* Stores the physical address of elf header of crash image. */
unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;


#ifndef CONFIG_RELOCATABLE
void __init reserve_kdump_trampoline(void)
void __init reserve_kdump_trampoline(void)
{
{
	lmb_reserve(0, KDUMP_RESERVE_LIMIT);
	lmb_reserve(0, KDUMP_RESERVE_LIMIT);
@@ -68,6 +69,7 @@ void __init setup_kdump_trampoline(void)


	DBG(" <- setup_kdump_trampoline()\n");
	DBG(" <- setup_kdump_trampoline()\n");
}
}
#endif /* CONFIG_RELOCATABLE */


/*
/*
 * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
 * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
+33 −6
Original line number Original line Diff line number Diff line
@@ -97,6 +97,12 @@ __secondary_hold_spinloop:
__secondary_hold_acknowledge:
__secondary_hold_acknowledge:
	.llong	0x0
	.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
#ifdef CONFIG_PPC_ISERIES
	/*
	/*
	 * At offset 0x20, there is a pointer to iSeries LPAR data.
	 * 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 */
	/* process relocations for the final address of the kernel */
	lis	r25,PAGE_OFFSET@highest	/* compute virtual base of kernel */
	lis	r25,PAGE_OFFSET@highest	/* compute virtual base of kernel */
	sldi	r25,r25,32
	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
	bl	.relocate
#endif
#endif


@@ -1398,11 +1410,26 @@ _STATIC(__after_prom_start)
	li	r3,0			/* target addr */
	li	r3,0			/* target addr */
	mr.	r4,r26			/* In some cases the loader may  */
	mr.	r4,r26			/* In some cases the loader may  */
	beq	9f			/* have already put us at zero */
	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 */
	li	r6,0x100		/* Start offset, the first 0x100 */
					/* bytes were copied earlier.	 */
					/* 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	 */
	bl	.copy_and_flush		/* copy the first n bytes	 */
					/* this includes the code being	 */
					/* this includes the code being	 */
					/* executed here.		 */
					/* executed here.		 */
@@ -1411,15 +1438,15 @@ _STATIC(__after_prom_start)
	mtctr	r8
	mtctr	r8
	bctr
	bctr


p_end:	.llong	_end - _stext

4:	/* Now copy the rest of the kernel up to _end */
4:	/* Now copy the rest of the kernel up to _end */
	addis	r5,r26,(p_end - _stext)@ha
	addis	r5,r26,(p_end - _stext)@ha
	ld	r5,(p_end - _stext)@l(r5)	/* get _end */
	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
9:	b	.start_here_multiplatform


p_end:	.llong	_end - _stext

/*
/*
 * Copy routine used to copy the kernel to start at physical address 0
 * Copy routine used to copy the kernel to start at physical address 0
 * and flush and invalidate the caches as needed.
 * and flush and invalidate the caches as needed.
Loading