Skip to contentSkip to conversation

Kdump support for classic PPC

PATCH In review Anton Vorontsov 3 participants 14 messages Dec 17, 2008 – Jan 7, 2009 PowerPC

lore
Share & tools
lore
#0 lore raw

cover Kdump support for classic PPC

Hi all,

This is Kdump part of the older series[1] posted few months ago.

Yeah, I didn't bother with relocatable kernel support (yet), I just want to consolidate a position of the working Kdump implementation, and then we can improve it as time goes by.

Other than that, all the comments that were previously made were addressed in this series. Hope this can make it into 2.6.29.

Thanks,

[1] http://ozlabs.org/pipermail/linuxppc-dev/2008-August/061161.html

Signature · 3 lines
Anton Vorontsov
email: [email protected]
irc://irc.freenode.net/bd2
#1 lore raw

PATCH 1/7 powerpc: Prepare xmon_save_regs for use with kdump

Today the arch/powerpc/xmon/setjmp.S file contains only the xmon_save_regs function. We want to use it for kdump purposes, so let's move the file into arch/powerpc/kernel/ and give the function a more generic name (ppc_save_regs).

---

This is "git-format-patch -M"-style patch.

 arch/powerpc/include/asm/reg.h                     |    4 ++++
 arch/powerpc/kernel/Makefile                       |    4 ++++
 .../{xmon/setjmp.S => kernel/ppc_save_regs.S}      |    2 +-
 arch/powerpc/xmon/Makefile                         |    2 +-
 arch/powerpc/xmon/xmon.c                           |    5 ++---
 5 files changed, 12 insertions(+), 5 deletions(-)
 rename arch/powerpc/{xmon/setjmp.S => kernel/ppc_save_regs.S} (98%)
arch/powerpc/include/asm/reg.h +4 -0
index c6d1ab6..f484a34 100644
@@ -783,6 +783,10 @@ extern void scom970_write(unsigned int address, unsigned long value);
 #define __get_SP()	({unsigned long sp; \
 			asm volatile("mr %0,1": "=r" (sp)); sp;})
 
+struct pt_regs;
+
+extern void ppc_save_regs(struct pt_regs *regs);
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_REG_H */
arch/powerpc/kernel/Makefile +4 -0
index 92673b4..616c889 100644
@@ -102,6 +102,10 @@ endif
 
 obj-$(CONFIG_PPC64)		+= $(obj64-y)
 
+ifneq ($(CONFIG_XMON),)
+obj-y				+= ppc_save_regs.o
+endif
+
 extra-$(CONFIG_PPC_FPU)		+= fpu.o
 extra-$(CONFIG_PPC64)		+= entry_64.o
 
arch/powerpc/kernel/ppc_save_regs.S renamed from arch/powerpc/xmon/setjmp.S +1 -1
similarity index 98%
rename from arch/powerpc/xmon/setjmp.S
rename to arch/powerpc/kernel/ppc_save_regs.S
index 04c0b30..5113bd2 100644
@@ -22,7 +22,7 @@
  * that will be different for 32-bit and 64-bit, because of the
  * different ABIs, though).
  */
-_GLOBAL(xmon_save_regs)
+_GLOBAL(ppc_save_regs)
 	PPC_STL	r0,0*SZL(r3)
 	PPC_STL	r2,2*SZL(r3)
 	PPC_STL	r3,3*SZL(r3)
arch/powerpc/xmon/Makefile +1 -1
index 51d9758..9cb03b7 100644
@@ -4,7 +4,7 @@ ifdef CONFIG_PPC64
 EXTRA_CFLAGS += -mno-minimal-toc
 endif
 
-obj-y			+= xmon.o setjmp.o start.o nonstdio.o
+obj-y			+= xmon.o start.o nonstdio.o
 
 ifdef CONFIG_XMON_DISASSEMBLY
 obj-y			+= ppc-dis.o ppc-opc.o
arch/powerpc/xmon/xmon.c +2 -3
index 076368c..8dfad7d 100644
@@ -41,6 +41,7 @@
 #include <asm/spu_priv1.h>
 #include <asm/firmware.h>
 #include <asm/setjmp.h>
+#include <asm/reg.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
@@ -159,8 +160,6 @@ static int xmon_no_auto_backtrace;
 extern void xmon_enter(void);
 extern void xmon_leave(void);
 
-extern void xmon_save_regs(struct pt_regs *);
-
 #ifdef CONFIG_PPC64
 #define REG		"%.16lx"
 #define REGS_PER_LINE	4
@@ -532,7 +531,7 @@ int xmon(struct pt_regs *excp)
 	struct pt_regs regs;
 
 	if (excp == NULL) {
-		xmon_save_regs(&regs);
+		ppc_save_regs(&regs);
 		excp = &regs;
 	}
 
Signature · 1 line
1.5.6.5
#2 lore raw

PATCH 1/7 powerpc: Prepare xmon_save_regs for use with kdump

Today the arch/powerpc/xmon/setjmp.S file contains only the xmon_save_regs function. We want to use it for kdump purposes, so let's move the file into arch/powerpc/kernel/ and give the function a more generic name (ppc_save_regs).

---

The same patch but suitable for patch(1), quilt users would appreciate. ;-)

 arch/powerpc/include/asm/reg.h      |    4 ++
 arch/powerpc/kernel/Makefile        |    4 ++
 arch/powerpc/kernel/ppc_save_regs.S |   74 +++++++++++++++++++++++++++++++++++
 arch/powerpc/xmon/Makefile          |    2 +-
 arch/powerpc/xmon/setjmp.S          |   74 -----------------------------------
 arch/powerpc/xmon/xmon.c            |    5 +-
 6 files changed, 85 insertions(+), 78 deletions(-)
 create mode 100644 arch/powerpc/kernel/ppc_save_regs.S
 delete mode 100644 arch/powerpc/xmon/setjmp.S
arch/powerpc/include/asm/reg.h +4 -0
index c6d1ab6..f484a34 100644
@@ -783,6 +783,10 @@ extern void scom970_write(unsigned int address, unsigned long value);
 #define __get_SP()	({unsigned long sp; \
 			asm volatile("mr %0,1": "=r" (sp)); sp;})
 
+struct pt_regs;
+
+extern void ppc_save_regs(struct pt_regs *regs);
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_REG_H */
arch/powerpc/kernel/Makefile +4 -0
index 92673b4..616c889 100644
@@ -102,6 +102,10 @@ endif
 
 obj-$(CONFIG_PPC64)		+= $(obj64-y)
 
+ifneq ($(CONFIG_XMON),)
+obj-y				+= ppc_save_regs.o
+endif
+
 extra-$(CONFIG_PPC_FPU)		+= fpu.o
 extra-$(CONFIG_PPC64)		+= entry_64.o
 
arch/powerpc/kernel/ppc_save_regs.S new file +74 -0

74 lines not on this page · raw message

arch/powerpc/xmon/Makefile +1 -1
index 51d9758..9cb03b7 100644
@@ -4,7 +4,7 @@ ifdef CONFIG_PPC64
 EXTRA_CFLAGS += -mno-minimal-toc
 endif
 
-obj-y			+= xmon.o setjmp.o start.o nonstdio.o
+obj-y			+= xmon.o start.o nonstdio.o
 
 ifdef CONFIG_XMON_DISASSEMBLY
 obj-y			+= ppc-dis.o ppc-opc.o
arch/powerpc/xmon/setjmp.S deleted +0 -74

74 lines not on this page · raw message

arch/powerpc/xmon/xmon.c +2 -3
index 076368c..8dfad7d 100644
@@ -41,6 +41,7 @@
 #include <asm/spu_priv1.h>
 #include <asm/firmware.h>
 #include <asm/setjmp.h>
+#include <asm/reg.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
@@ -159,8 +160,6 @@ static int xmon_no_auto_backtrace;
 extern void xmon_enter(void);
 extern void xmon_leave(void);
 
-extern void xmon_save_regs(struct pt_regs *);
-
 #ifdef CONFIG_PPC64
 #define REG		"%.16lx"
 #define REGS_PER_LINE	4
@@ -532,7 +531,7 @@ int xmon(struct pt_regs *excp)
 	struct pt_regs regs;
 
 	if (excp == NULL) {
-		xmon_save_regs(&regs);
+		ppc_save_regs(&regs);
 		excp = &regs;
 	}
 
Signature · 1 line
1.5.6.5
#3 lore raw

PATCH 2/7 powerpc/32/kdump: Implement crash_setup_regs() using ppc_save_regs()

In reply to Anton Vorontsov

This patch replaces dummy function with full-fledged crash_setup_regs() implementation. On PPC32 we simply use ppc_save_regs function to dump the registers.

---
 arch/powerpc/include/asm/kexec.h |   15 ++++++---------
 arch/powerpc/kernel/Makefile     |    2 +-
 2 files changed, 7 insertions(+), 10 deletions(-)
arch/powerpc/include/asm/kexec.h +6 -9
index 3736d9b..6dbffc9 100644
@@ -33,12 +33,12 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/cpumask.h>
+#include <asm/reg.h>
 
 typedef void (*crash_shutdown_t)(void);
 
 #ifdef CONFIG_KEXEC
 
-#ifdef __powerpc64__
 /*
  * This function is responsible for capturing register states if coming
  * via panic or invoking dump using sysrq-trigger.
@@ -48,6 +48,7 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
 {
 	if (oldregs)
 		memcpy(newregs, oldregs, sizeof(*newregs));
+#ifdef __powerpc64__
 	else {
 		/* FIXME Merge this with xmon_save_regs ?? */
 		unsigned long tmp1, tmp2;
@@ -100,15 +101,11 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
 			: "b" (newregs)
 			: "memory");
 	}
-}
 #else
-/*
- * Provide a dummy definition to avoid build failures. Will remain
- * empty till crash dump support is enabled.
- */
-static inline void crash_setup_regs(struct pt_regs *newregs,
-					struct pt_regs *oldregs) { }
-#endif /* !__powerpc64 __ */
+	else
+		ppc_save_regs(newregs);
+#endif /* __powerpc64__ */
+}
 
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
 					  master to copy new code to 0 */
arch/powerpc/kernel/Makefile +1 -1
index 616c889..089209a 100644
@@ -102,7 +102,7 @@ endif
 
 obj-$(CONFIG_PPC64)		+= $(obj64-y)
 
-ifneq ($(CONFIG_XMON),)
+ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
 obj-y				+= ppc_save_regs.o
 endif
 
Signature · 1 line
1.5.6.5
#4 lore raw

PATCH 3/7 powerpc/32: Setup OF properties for kdump

In reply to Anton Vorontsov

From: Dale Farnsworth <[email protected]>

Refactor the setting of kexec OF properties, moving the common code from machine_kexec_64.c to machine_kexec.c where it can be used on both ppc64 and ppc32. This will be needed for kdump to work on ppc32 platforms.

---
 arch/powerpc/kernel/machine_kexec.c    |   36 ++++++++++++++++++++
 arch/powerpc/kernel/machine_kexec_64.c |   56 ++-----------------------------
 2 files changed, 40 insertions(+), 52 deletions(-)
arch/powerpc/kernel/machine_kexec.c +36 -0
index 4f797c0..b3abebb 100644
@@ -120,6 +120,7 @@ int overlaps_crashkernel(unsigned long start, unsigned long size)
 
 /* Values we need to export to the second kernel via the device tree. */
 static unsigned long kernel_end;
+static unsigned long crashk_size;
 
 static struct property kernel_end_prop = {
 	.name = "linux,kernel-end",
@@ -127,6 +128,39 @@ static struct property kernel_end_prop = {
 	.value = &kernel_end,
 };
 
+static struct property crashk_base_prop = {
+	.name = "linux,crashkernel-base",
+	.length = sizeof(unsigned long),
+	.value = &crashk_res.start,
+};
+
+static struct property crashk_size_prop = {
+	.name = "linux,crashkernel-size",
+	.length = sizeof(unsigned long),
+	.value = &crashk_size,
+};
+
+static void __init export_crashk_values(struct device_node *node)
+{
+	struct property *prop;
+
+	/* There might be existing crash kernel properties, but we can't
+	 * be sure what's in them, so remove them. */
+	prop = of_find_property(node, "linux,crashkernel-base", NULL);
+	if (prop)
+		prom_remove_property(node, prop);
+
+	prop = of_find_property(node, "linux,crashkernel-size", NULL);
+	if (prop)
+		prom_remove_property(node, prop);
+
+	if (crashk_res.start != 0) {
+		prom_add_property(node, &crashk_base_prop);
+		crashk_size = crashk_res.end - crashk_res.start + 1;
+		prom_add_property(node, &crashk_size_prop);
+	}
+}
+
 static int __init kexec_setup(void)
 {
 	struct device_node *node;
@@ -145,6 +179,8 @@ static int __init kexec_setup(void)
 	kernel_end = __pa(_end);
 	prom_add_property(node, &kernel_end_prop);
 
+	export_crashk_values(node);
+
 	of_node_put(node);
 	return 0;
 }
arch/powerpc/kernel/machine_kexec_64.c +4 -52

76 lines not on this page · raw message

Signature · 1 line
1.5.6.5
#5 lore raw

Re: [PATCH 3/7] powerpc/32: Setup OF properties for kdump

Quoted 19 lines · Anton Vorontsov

From: Dale Farnsworth <[email protected]>

Refactor the setting of kexec OF properties, moving the common code from machine_kexec_64.c to machine_kexec.c where it can be used on both ppc64 and ppc32. This will be needed for kdump to work on ppc32 platforms.

---
 arch/powerpc/kernel/machine_kexec.c    |   36 ++++++++++++++++++++
 arch/powerpc/kernel/machine_kexec_64.c |   56 ++-----------------------------
 2 files changed, 40 insertions(+), 52 deletions(-)
arch/powerpc/kernel/machine_kexec.c +0 -0
index 4f797c0..b3abebb 100644

arch/powerpc/kernel/machine_kexec.c int overlaps_crashkernel(unsigned long start, unsigned long size) · line 126

Quoted 7 lines
arch/powerpc/kernel/machine_kexec.c +1 -0
@@ -120,6 +120,7 @@ int overlaps_crashkernel(unsigned long start, unsigned long size)
 
 /* Values we need to export to the second kernel via the device tree. */
 static unsigned long kernel_end;
+static unsigned long crashk_size;
 
 static struct property kernel_end_prop = {
 	.name = "linux,kernel-end",

This patch doesn't apply. The current version of machine_kexec.c ends with overlaps_crashkernel. There's no kernel_end or kernel_end_prop in that file. Is there a preceding patch that needs to be applied first?

Paul.

#6 lore raw

Re: [PATCH 3/7] powerpc/32: Setup OF properties for kdump

Quoted 26 lines · Paul Mackerras
Quoted 24 lines · Anton Vorontsov

From: Dale Farnsworth <[email protected]>

Refactor the setting of kexec OF properties, moving the common code from machine_kexec_64.c to machine_kexec.c where it can be used on both ppc64 and ppc32. This will be needed for kdump to work on ppc32 platforms.

---
 arch/powerpc/kernel/machine_kexec.c    |   36 ++++++++++++++++++++
 arch/powerpc/kernel/machine_kexec_64.c |   56 ++-----------------------------
 2 files changed, 40 insertions(+), 52 deletions(-)
arch/powerpc/kernel/machine_kexec.c +1 -0
index 4f797c0..b3abebb 100644
@@ -120,6 +120,7 @@ int overlaps_crashkernel(unsigned long start, unsigned long size)
 
 /* Values we need to export to the second kernel via the device tree. */
 static unsigned long kernel_end;
+static unsigned long crashk_size;
 
Quoted 7 lines

arch/powerpc/kernel/machine_kexec.c int overlaps_crashkernel(unsigned long start, unsigned long size) · line 126

Quoted 2 lines
arch/powerpc/kernel/machine_kexec.c +0 -0
 static struct property kernel_end_prop = {
 	.name = "linux,kernel-end",

This patch doesn't apply. The current version of machine_kexec.c ends with overlaps_crashkernel. There's no kernel_end or kernel_end_prop in that file. Is there a preceding patch that needs to be applied first?

Yes, this patch set depend on another patch from the Kexec series:
[1/3] powerpc: Setup OF properties for ppc32 kexec
http://patchwork.ozlabs.org/patch/14280/

Sorry, I forgot to mention this in the introductory post.

Signature · 3 lines
Anton Vorontsov
email: [email protected]
irc://irc.freenode.net/bd2
#7 lore raw

PATCH 4/7 powerpc/32: Allow to ioremap RAM addresses for kdump kernel

In reply to Anton Vorontsov

While for debugging it is good to catch bogus users of ioremap, though for kdump support it is more convenient to use ioremap for copy_oldmem_page() (exactly as we do for PPC64 currently).

Note that copy_oldmem_page() calls __ioremap with flags set to '0', so it should be safe with the regard to the caches.

The other option is to use kmap_atomic_pfn()[1], but it will not work for kernels compiled without HIGHMEM.

That is, on a board with 256MB RAM and crashkernel=64M@32M case, the !HIGHMEM capturing kernel maps 0-96M range, which does not include all the memory needed to capture the dump. And, obviously, accessing anything upper than 96M will cause faults.

[1] http://ozlabs.org/pipermail/linuxppc-dev/2007-November/046747.html

---
 arch/powerpc/mm/pgtable_32.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
arch/powerpc/mm/pgtable_32.c +2 -0
index 3414724..cd56097 100644
@@ -173,6 +173,7 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
 	if (p < 16*1024*1024)
 		p += _ISA_MEM_BASE;
 
+#ifndef CONFIG_CRASH_DUMP
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using.
 	 * mem_init() sets high_memory so only do the check after that.
@@ -182,6 +183,7 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
 		       (unsigned long long)p, __builtin_return_address(0));
 		return NULL;
 	}
+#endif
 
 	if (size == 0)
 		return NULL;
Signature · 1 line
1.5.6.5
#8 lore raw

PATCH 5/7 powerpc/32: Add the ability for a classic ppc kernel to be loaded at 32M

In reply to Anton Vorontsov

From: Dale Farnsworth <[email protected]>

Add the ability for a classic ppc kernel to be loaded at an address of 32MB. This done by fixing a few places that assume we are loaded at address 0, and by changing several uses of KERNELBASE to use PAGE_OFFSET, instead.

---
 arch/powerpc/include/asm/ppc_asm.h |    4 ++--
 arch/powerpc/kernel/head_32.S      |   11 ++++++-----
 arch/powerpc/mm/init_32.c          |    2 +-
 arch/powerpc/mm/pgtable_32.c       |    4 ++--
 arch/powerpc/mm/ppc_mmu_32.c       |    8 ++++----
 5 files changed, 15 insertions(+), 14 deletions(-)
arch/powerpc/include/asm/ppc_asm.h +2 -2
index c4a029c..1a0d628 100644
@@ -425,14 +425,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define fromreal(rd)	tovirt(rd,rd)
 
 #define tophys(rd,rs)				\
-0:	addis	rd,rs,-KERNELBASE@h;		\
+0:	addis	rd,rs,-PAGE_OFFSET@h;		\
 	.section ".vtop_fixup","aw";		\
 	.align  1;				\
 	.long   0b;				\
 	.previous
 
 #define tovirt(rd,rs)				\
-0:	addis	rd,rs,KERNELBASE@h;		\
+0:	addis	rd,rs,PAGE_OFFSET@h;		\
 	.section ".ptov_fixup","aw";		\
 	.align  1;				\
 	.long   0b;				\
arch/powerpc/kernel/head_32.S +6 -5
index 0c32682..97338d9 100644
@@ -182,7 +182,8 @@ __after_mmu_off:
 	bl	reloc_offset
 	mr	r26,r3
 	addis	r4,r3,KERNELBASE@h	/* current address of _start */
-	cmpwi	0,r4,0			/* are we already running at 0? */
+	lis	r5,PHYSICAL_START@h
+	cmplw	0,r4,r5			/* already running at PHYSICAL_START? */
 	bne	relocate_kernel
 /*
  * we now have the 1st 16M of ram mapped with the bats.
@@ -810,13 +811,13 @@ giveup_altivec:
 
 /*
  * This code is jumped to from the startup code to copy
- * the kernel image to physical address 0.
+ * the kernel image to physical address PHYSICAL_START.
  */
 relocate_kernel:
 	addis	r9,r26,klimit@ha	/* fetch klimit */
 	lwz	r25,klimit@l(r9)
 	addis	r25,r25,-KERNELBASE@h
-	li	r3,0			/* Destination base address */
+	lis	r3,PHYSICAL_START@h	/* Destination base address */
 	li	r6,0			/* Destination offset */
 	li	r5,0x4000		/* # bytes of memory to copy */
 	bl	copy_and_flush		/* copy the first 0x4000 bytes */
@@ -1178,11 +1179,11 @@ mmu_off:
 
 /*
  * Use the first pair of BAT registers to map the 1st 16MB
- * of RAM to KERNELBASE.  From this point on we can't safely
+ * of RAM to PAGE_OFFSET.  From this point on we can't safely
  * call OF any more.
  */
 initial_bats:
-	lis	r11,KERNELBASE@h
+	lis	r11,PAGE_OFFSET@h
 	mfspr	r9,SPRN_PVR
 	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
 	cmpwi	0,r9,1
arch/powerpc/mm/init_32.c +1 -1
index 388ceda..4ac0e4e 100644
@@ -49,7 +49,7 @@
 
 #if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
 /* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */
-#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - KERNELBASE))
+#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - PAGE_OFFSET))
 #error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL"
 #endif
 #endif
arch/powerpc/mm/pgtable_32.c +2 -2
index cd56097..8cba46f 100644
@@ -269,7 +269,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
 }
 
 /*
- * Map in a big chunk of physical memory starting at KERNELBASE.
+ * Map in a big chunk of physical memory starting at PAGE_OFFSET.
  */
 void __init mapin_ram(void)
 {
@@ -278,7 +278,7 @@ void __init mapin_ram(void)
 	int ktext;
 
 	s = mmu_mapin_ram();
-	v = KERNELBASE + s;
+	v = PAGE_OFFSET + s;
 	p = memstart_addr + s;
 	for (; s < total_lowmem; s += PAGE_SIZE) {
 		ktext = ((char *) v >= _stext && (char *) v < etext);
arch/powerpc/mm/ppc_mmu_32.c +4 -4
index 6aa1208..49b195e 100644
@@ -95,16 +95,16 @@ unsigned long __init mmu_mapin_ram(void)
 			break;
 	}
 
-	setbat(2, KERNELBASE, 0, bl, _PAGE_RAM);
-	done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
+	setbat(2, PAGE_OFFSET, 0, bl, _PAGE_RAM);
+	done = (unsigned long)bat_addrs[2].limit - PAGE_OFFSET + 1;
 	if ((done < tot) && !bat_addrs[3].limit) {
 		/* use BAT3 to cover a bit more */
 		tot -= done;
 		for (bl = 128<<10; bl < max_size; bl <<= 1)
 			if (bl * 2 > tot)
 				break;
-		setbat(3, KERNELBASE+done, done, bl, _PAGE_RAM);
-		done = (unsigned long)bat_addrs[3].limit - KERNELBASE + 1;
+		setbat(3, PAGE_OFFSET+done, done, bl, _PAGE_RAM);
+		done = (unsigned long)bat_addrs[3].limit - PAGE_OFFSET + 1;
 	}
 
 	return done;
Signature · 1 line
1.5.6.5
#9 lore raw

PATCH 6/7 powerpc/32: Wire up the trampoline code for kdump

In reply to Anton Vorontsov

From: Dale Farnsworth <[email protected]>

Wire up the trampoline code for ppc32 to relay exceptions from the vectors at address 0 to vectors at address 32MB, and modify Kconfig to enable Kdump support for all classic powerpcs.

---
 arch/powerpc/Kconfig             |    2 +-
 arch/powerpc/include/asm/kdump.h |   13 +++++++++++++
 arch/powerpc/kernel/setup_32.c   |    2 ++
 3 files changed, 16 insertions(+), 1 deletions(-)
arch/powerpc/Kconfig +1 -1
index be4f99b..f7f5448 100644
@@ -326,7 +326,7 @@ config KEXEC
 
 config CRASH_DUMP
 	bool "Build a kdump crash kernel"
-	depends on PPC_MULTIPLATFORM && PPC64 && RELOCATABLE
+	depends on (PPC64 && RELOCATABLE) || 6xx
 	help
 	  Build a kernel suitable for use as a kdump capture kernel.
 	  The same kernel binary can be used as production kernel and dump
arch/powerpc/include/asm/kdump.h +13 -0
index b07ebb9..5ebfe5d 100644
@@ -1,6 +1,8 @@
 #ifndef _PPC64_KDUMP_H
 #define _PPC64_KDUMP_H
 
+#include <asm/page.h>
+
 /* Kdump kernel runs at 32 MB, change at your peril. */
 #define KDUMP_KERNELBASE	0x2000000
 
@@ -11,8 +13,19 @@
 
 #ifdef CONFIG_CRASH_DUMP
 
+/*
+ * On PPC64 translation is disabled during trampoline setup, so we use
+ * physical addresses. Though on PPC32 translation is already enabled,
+ * so we can't do the same. Luckily create_trampoline() creates relative
+ * branches, so we can just add the PAGE_OFFSET and don't worry about it.
+ */
+#ifdef __powerpc64__
 #define KDUMP_TRAMPOLINE_START	0x0100
 #define KDUMP_TRAMPOLINE_END	0x3000
+#else
+#define KDUMP_TRAMPOLINE_START	(0x0100 + PAGE_OFFSET)
+#define KDUMP_TRAMPOLINE_END	(0x3000 + PAGE_OFFSET)
+#endif /* __powerpc64__ */
 
 #define KDUMP_MIN_TCE_ENTRIES	2048
 
arch/powerpc/kernel/setup_32.c +2 -0
index 086c23c..9ca1d2b 100644
@@ -121,6 +121,8 @@ notrace void __init machine_init(unsigned long dt_ptr)
 
 	probe_machine();
 
+	setup_kdump_trampoline();
+
 #ifdef CONFIG_6xx
 	if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
 	    cpu_has_feature(CPU_FTR_CAN_NAP))
Signature · 1 line
1.5.6.5
#10 lore raw

PATCH 7/7 powerpc/64/kdump: Use ppc_save_regs() in crash_setup_regs()

In reply to Anton Vorontsov

The patch replaces internal registers dump implementation with ppc_save_regs(). From now on PPC64 and PPC32 are using the same code for crash_setup_regs().

NOTE: The old regs dump implementation was capturing SP (r1) directly as is, so you could see crash_kexec() function on top of the back-trace. But ppc_save_regs() goes up one stack frame, so you'll not see it anymore, at the top-level you'll see who actually triggered the crash dump instead.

---

p.s.
The patch is the last in the series, so you can easily drop it until somebody actually test it (I don't have any PPC64 machine, so I'm looking for volunteers. :-)

 arch/powerpc/include/asm/kexec.h |   55 --------------------------------------
 1 files changed, 0 insertions(+), 55 deletions(-)
arch/powerpc/include/asm/kexec.h +0 -55
index 6dbffc9..7e06b43 100644
@@ -48,63 +48,8 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
 {
 	if (oldregs)
 		memcpy(newregs, oldregs, sizeof(*newregs));
-#ifdef __powerpc64__
-	else {
-		/* FIXME Merge this with xmon_save_regs ?? */
-		unsigned long tmp1, tmp2;
-		__asm__ __volatile__ (
-			"std    0,0(%2)\n"
-			"std    1,8(%2)\n"
-			"std    2,16(%2)\n"
-			"std    3,24(%2)\n"
-			"std    4,32(%2)\n"
-			"std    5,40(%2)\n"
-			"std    6,48(%2)\n"
-			"std    7,56(%2)\n"
-			"std    8,64(%2)\n"
-			"std    9,72(%2)\n"
-			"std    10,80(%2)\n"
-			"std    11,88(%2)\n"
-			"std    12,96(%2)\n"
-			"std    13,104(%2)\n"
-			"std    14,112(%2)\n"
-			"std    15,120(%2)\n"
-			"std    16,128(%2)\n"
-			"std    17,136(%2)\n"
-			"std    18,144(%2)\n"
-			"std    19,152(%2)\n"
-			"std    20,160(%2)\n"
-			"std    21,168(%2)\n"
-			"std    22,176(%2)\n"
-			"std    23,184(%2)\n"
-			"std    24,192(%2)\n"
-			"std    25,200(%2)\n"
-			"std    26,208(%2)\n"
-			"std    27,216(%2)\n"
-			"std    28,224(%2)\n"
-			"std    29,232(%2)\n"
-			"std    30,240(%2)\n"
-			"std    31,248(%2)\n"
-			"mfmsr  %0\n"
-			"std    %0, 264(%2)\n"
-			"mfctr  %0\n"
-			"std    %0, 280(%2)\n"
-			"mflr   %0\n"
-			"std    %0, 288(%2)\n"
-			"bl     1f\n"
-		"1:     mflr   %1\n"
-			"std    %1, 256(%2)\n"
-			"mtlr   %0\n"
-			"mfxer  %0\n"
-			"std    %0, 296(%2)\n"
-			: "=&r" (tmp1), "=&r" (tmp2)
-			: "b" (newregs)
-			: "memory");
-	}
-#else
 	else
 		ppc_save_regs(newregs);
-#endif /* __powerpc64__ */
 }
 
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
Signature · 1 line
1.5.6.5
#11 lore raw

Re: [PATCH 7/7] powerpc/64/kdump: Use ppc_save_regs() in crash_setup_regs()

Quoted 4 lines · Anton Vorontsov

The patch replaces internal registers dump implementation with ppc_save_regs(). From now on PPC64 and PPC32 are using the same code for crash_setup_regs().

Quoted 8 lines

NOTE: The old regs dump implementation was capturing SP (r1) directly as is, so you could see crash_kexec() function on top of the back-trace. But ppc_save_regs() goes up one stack frame, so you'll not see it anymore, at the top-level you'll see who actually triggered the crash dump instead.

---

Note that ppc_save_regs() for some obscure reason isn't saving r1...

Is that a problem for you ? I think we should fix ppc_save_regs() anyway, it doesn't matter for xmon to save one more register and it will avoid nasty surprises in the long run.

Can you send an updated patch ?

Thanks !
Ben.

Quoted 76 lines

p.s.
The patch is the last in the series, so you can easily drop it until somebody actually test it (I don't have any PPC64 machine, so I'm looking for volunteers. :-)

 arch/powerpc/include/asm/kexec.h |   55 --------------------------------------
 1 files changed, 0 insertions(+), 55 deletions(-)
arch/powerpc/include/asm/kexec.h +0 -55
index 6dbffc9..7e06b43 100644
@@ -48,63 +48,8 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
 {
 	if (oldregs)
 		memcpy(newregs, oldregs, sizeof(*newregs));
-#ifdef __powerpc64__
-	else {
-		/* FIXME Merge this with xmon_save_regs ?? */
-		unsigned long tmp1, tmp2;
-		__asm__ __volatile__ (
-			"std    0,0(%2)\n"
-			"std    1,8(%2)\n"
-			"std    2,16(%2)\n"
-			"std    3,24(%2)\n"
-			"std    4,32(%2)\n"
-			"std    5,40(%2)\n"
-			"std    6,48(%2)\n"
-			"std    7,56(%2)\n"
-			"std    8,64(%2)\n"
-			"std    9,72(%2)\n"
-			"std    10,80(%2)\n"
-			"std    11,88(%2)\n"
-			"std    12,96(%2)\n"
-			"std    13,104(%2)\n"
-			"std    14,112(%2)\n"
-			"std    15,120(%2)\n"
-			"std    16,128(%2)\n"
-			"std    17,136(%2)\n"
-			"std    18,144(%2)\n"
-			"std    19,152(%2)\n"
-			"std    20,160(%2)\n"
-			"std    21,168(%2)\n"
-			"std    22,176(%2)\n"
-			"std    23,184(%2)\n"
-			"std    24,192(%2)\n"
-			"std    25,200(%2)\n"
-			"std    26,208(%2)\n"
-			"std    27,216(%2)\n"
-			"std    28,224(%2)\n"
-			"std    29,232(%2)\n"
-			"std    30,240(%2)\n"
-			"std    31,248(%2)\n"
-			"mfmsr  %0\n"
-			"std    %0, 264(%2)\n"
-			"mfctr  %0\n"
-			"std    %0, 280(%2)\n"
-			"mflr   %0\n"
-			"std    %0, 288(%2)\n"
-			"bl     1f\n"
-		"1:     mflr   %1\n"
-			"std    %1, 256(%2)\n"
-			"mtlr   %0\n"
-			"mfxer  %0\n"
-			"std    %0, 296(%2)\n"
-			: "=&r" (tmp1), "=&r" (tmp2)
-			: "b" (newregs)
-			: "memory");
-	}
-#else
 	else
 		ppc_save_regs(newregs);
-#endif /* __powerpc64__ */
 }
 
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
#12 lore raw

Re: [PATCH 7/7] powerpc/64/kdump: Use ppc_save_regs() in crash_setup_regs()

Quoted 11 lines · Benjamin Herrenschmidt
Quoted 10 lines · Anton Vorontsov

The patch replaces internal registers dump implementation with ppc_save_regs(). From now on PPC64 and PPC32 are using the same code for crash_setup_regs().

NOTE: The old regs dump implementation was capturing SP (r1) directly as is, so you could see crash_kexec() function on top of the back-trace. But ppc_save_regs() goes up one stack frame, so you'll not see it anymore, at the top-level you'll see who actually triggered the crash dump instead.

Quoted 8 lines
Quoted 2 lines

---

Note that ppc_save_regs() for some obscure reason isn't saving r1...

Is that a problem for you ? I think we should fix ppc_save_regs() anyway, it doesn't matter for xmon to save one more register and it will avoid nasty surprises in the long run.

AFAICS it saves r1:

       PPC_STL r0,0*SZL(r3)
       PPC_STL r2,2*SZL(r3)
       PPC_STL r3,3*SZL(r3)
       ...
       /* go up one stack frame for SP */
       PPC_LL  r4,0(r1)
       PPC_STL r4,1*SZL(r3)

This fact is mentioned in the patch description:

NOTE: The old regs dump implementation was capturing SP (r1) directly as is, so you could see crash_kexec() function on top of the back-trace. But ppc_save_regs() goes up one stack frame, so you'll not see it anymore, at the top-level you'll see who actually triggered the crash dump instead.

Do you see anything wrong in such behaviour?

Thanks,

Signature · 3 lines
Anton Vorontsov
email: [email protected]
irc://irc.freenode.net/bd2
#13 lore raw

Re: [PATCH 7/7] powerpc/64/kdump: Use ppc_save_regs() in crash_setup_regs()

Quoted 12 lines · Anton Vorontsov

AFAICS it saves r1:

       PPC_STL r0,0*SZL(r3)
       PPC_STL r2,2*SZL(r3)
       PPC_STL r3,3*SZL(r3)
       ...
       /* go up one stack frame for SP */
       PPC_LL  r4,0(r1)
       PPC_STL r4,1*SZL(r3)

This fact is mentioned in the patch description:

Quoted 8 lines

NOTE: The old regs dump implementation was capturing SP (r1) directly as is, so you could see crash_kexec() function on top of the
back-trace.
But ppc_save_regs() goes up one stack frame, so you'll not see it anymore, at the top-level you'll see who actually triggered the crash dump instead.

Do you see anything wrong in such behaviour?

No, just me being a bit blind looking at too many patches today :-)

Cheers,
Ben.