Skip to contentSkip to conversation

Kexec for PPC32 (6xx) machines

PATCH In review Anton Vorontsov 2 participants 7 messages Dec 16, 2008 – Dec 23, 2008

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover Kexec for PPC32 (6xx) machines

Hi all,

This is Kexec part of the larger series[1] posted few months ago. I eliminated Kdump part in this resend (will post it as a separate entity later).

Milton Miller hinted that current PPC32 Kexec implementation may not work on SMP hardware. I don't have any multi-core machines handy to actually try and/or fix it, but support for SMP should be
straightforward: just need to bring the secondary CPUs down before Kexec'ing (the code is already in the machine_kexec_64.c, just needs to be factored out).

The arch/powerpc/Kconfig already states that the Kexec support is experimental and may not work on certain hardware, so I don't see any reason to add !SMP dependency.

Anyway, the majority of boards are UP and they don't need any fancy care to work. So let's support them.

[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/3 powerpc: Setup OF properties for ppc32 kexec

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 is needed for kexec to work on ppc32 platforms.

---
 arch/powerpc/kernel/machine_kexec.c    |   34 ++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/machine_kexec_64.c |   24 ++++-----------------
 2 files changed, 39 insertions(+), 19 deletions(-)
arch/powerpc/kernel/machine_kexec.c +34 -0
index ac2a21f..037ade7 100644
@@ -13,8 +13,10 @@
 #include <linux/reboot.h>
 #include <linux/threads.h>
 #include <linux/lmb.h>
+#include <linux/of.h>
 #include <asm/machdep.h>
 #include <asm/prom.h>
+#include <asm/sections.h>
 
 void machine_crash_shutdown(struct pt_regs *regs)
 {
@@ -118,3 +120,35 @@ int overlaps_crashkernel(unsigned long start, unsigned long size)
 {
 	return (start + size) > crashk_res.start && start <= crashk_res.end;
 }
+
+/* Values we need to export to the second kernel via the device tree. */
+static unsigned long kernel_end;
+
+static struct property kernel_end_prop = {
+	.name = "linux,kernel-end",
+	.length = sizeof(unsigned long),
+	.value = &kernel_end,
+};
+
+static int __init kexec_setup(void)
+{
+	struct device_node *node;
+	struct property *prop;
+
+	node = of_find_node_by_path("/chosen");
+	if (!node)
+		return -ENOENT;
+
+	/* remove any stale properties so ours can be found */
+	prop = of_find_property(node, kernel_end_prop.name, NULL);
+	if (prop)
+		prom_remove_property(node, prop);
+
+	/* information needed by userspace when using default_machine_kexec */
+	kernel_end = __pa(_end);
+	prom_add_property(node, &kernel_end_prop);
+
+	of_node_put(node);
+	return 0;
+}
+late_initcall(kexec_setup);
arch/powerpc/kernel/machine_kexec_64.c +5 -19
index 3c4ca04..a89bce8 100644
@@ -289,7 +289,7 @@ void default_machine_kexec(struct kimage *image)
 }
 
 /* Values we need to export to the second kernel via the device tree. */
-static unsigned long htab_base, kernel_end;
+static unsigned long htab_base;
 
 static struct property htab_base_prop = {
 	.name = "linux,htab-base",
@@ -303,25 +303,20 @@ static struct property htab_size_prop = {
 	.value = &htab_size_bytes,
 };
 
-static struct property kernel_end_prop = {
-	.name = "linux,kernel-end",
-	.length = sizeof(unsigned long),
-	.value = &kernel_end,
-};
-
 static void __init export_htab_values(void)
 {
 	struct device_node *node;
 	struct property *prop;
 
+	/* On machines with no htab htab_address is NULL */
+	if (!htab_address)
+		return;
+
 	node = of_find_node_by_path("/chosen");
 	if (!node)
 		return;
 
 	/* remove any stale propertys so ours can be found */
-	prop = of_find_property(node, kernel_end_prop.name, NULL);
-	if (prop)
-		prom_remove_property(node, prop);
 	prop = of_find_property(node, htab_base_prop.name, NULL);
 	if (prop)
 		prom_remove_property(node, prop);
@@ -329,19 +324,10 @@ static void __init export_htab_values(void)
 	if (prop)
 		prom_remove_property(node, prop);
 
-	/* information needed by userspace when using default_machine_kexec */
-	kernel_end = __pa(_end);
-	prom_add_property(node, &kernel_end_prop);
-
-	/* On machines with no htab htab_address is NULL */
-	if (NULL == htab_address)
-		goto out;
-
 	htab_base = __pa(htab_address);
 	prom_add_property(node, &htab_base_prop);
 	prom_add_property(node, &htab_size_prop);
 
- out:
 	of_node_put(node);
 }
 
Signature · 1 line
1.5.6.5
#2 lore raw

PATCH 2/3 powerpc: Make default kexec/crash_kernel ops implicit

In reply to Anton Vorontsov

This patch removes need for each platform to specify default kexec and crash kernel ops, thus effectively adds a working kexec support for most boards.

Platforms that can't cope with default ops will explode in some weird way (a hang or reboot is most likely), which means that the board's kexec support should be fixed or blacklisted via dummy _prepare callback returning -ENOSYS.

---
 arch/powerpc/kernel/machine_kexec.c |   21 +++++++++------------
 1 files changed, 9 insertions(+), 12 deletions(-)
arch/powerpc/kernel/machine_kexec.c +9 -12
index 037ade7..4f797c0 100644
@@ -22,6 +22,8 @@ void machine_crash_shutdown(struct pt_regs *regs)
 {
 	if (ppc_md.machine_crash_shutdown)
 		ppc_md.machine_crash_shutdown(regs);
+	else
+		default_machine_crash_shutdown(regs);
 }
 
 /*
@@ -33,11 +35,8 @@ int machine_kexec_prepare(struct kimage *image)
 {
 	if (ppc_md.machine_kexec_prepare)
 		return ppc_md.machine_kexec_prepare(image);
-	/*
-	 * Fail if platform doesn't provide its own machine_kexec_prepare
-	 * implementation.
-	 */
-	return -ENOSYS;
+	else
+		return default_machine_kexec_prepare(image);
 }
 
 void machine_kexec_cleanup(struct kimage *image)
@@ -54,13 +53,11 @@ void machine_kexec(struct kimage *image)
 {
 	if (ppc_md.machine_kexec)
 		ppc_md.machine_kexec(image);
-	else {
-		/*
-		 * Fall back to normal restart if platform doesn't provide
-		 * its own kexec function, and user insist to kexec...
-		 */
-		machine_restart(NULL);
-	}
+	else
+		default_machine_kexec(image);
+
+	/* Fall back to normal restart if we're still alive. */
+	machine_restart(NULL);
 	for(;;);
 }
 
Signature · 1 line
1.5.6.5
#3 lore raw

Re: [PATCH 2/3] powerpc: Make default kexec/crash_kernel ops implicit

Quoted 8 lines · Anton Vorontsov

This patch removes need for each platform to specify default kexec and crash kernel ops, thus effectively adds a working kexec support for most boards.

Platforms that can't cope with default ops will explode in some weird way (a hang or reboot is most likely), which means that the board's kexec support should be fixed or blacklisted via dummy _prepare callback returning -ENOSYS.

But where is the patch to do this?

The chance of kexec working on some random machine that's never been tested is pretty slim, every driver needs to be aware its hardware might be in a weird state, so enabling it by default is not a good idea IMHO.

cheers

Signature · 8 lines
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
#4 lore raw

Re: [PATCH 2/3] powerpc: Make default kexec/crash_kernel ops implicit

Quoted 11 lines · Michael Ellerman
Quoted 8 lines · Anton Vorontsov

This patch removes need for each platform to specify default kexec and crash kernel ops, thus effectively adds a working kexec support for most boards.

Platforms that can't cope with default ops will explode in some weird way (a hang or reboot is most likely), which means that the board's kexec support should be fixed or blacklisted via dummy _prepare callback returning -ENOSYS.

But where is the patch to do this?

The -ENOSYS dummy callback is a last resort thing to do when nobody cares or it's impossible to fix the Kexec on some board. We don't have any such boards (yet).

Quoted 3 lines

The chance of kexec working on some random machine that's never been tested is pretty slim, every driver needs to be aware its hardware might be in a weird state,

The boards setup isn't always static. The Kexec might work perfectly well on a standalone board, but might hang with some weird PCI device attached to it (think that it might need some PCI fixup on shutdown).

I think that a "Kexec tested to work on a particular board" term just doesn't exist. It might work, but it might hang with other setup on the *same* board.

But in practice the Kexec work on every 6xx board I have. And I have pretty much of Freescale boards (almost all from the 83xx series), and I don't think it's practical to add #ifdef CONFIG_KEXEC into the every board file...

Thus I don't think that disabling Kexec by default is a good idea.

Plus, note that PowerPC port is the only one that disables Kexec by default (all other arches permit Kexec by default).

Quoted 1 line

so enabling it by default is not a good idea IMHO.

Why? A hang or plain/watchdog reboot is OK since kexec is as dangerous as trying to boot another kernel using "reboot -> u-boot -> new kernel" sequence -- it might not work, the new kernel might not boot for some reason.

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

Re: [PATCH 2/3] powerpc: Make default kexec/crash_kernel ops implicit

Quoted 11 lines · Anton Vorontsov
Quoted 10 lines · Michael Ellerman
Quoted 8 lines · Anton Vorontsov

This patch removes need for each platform to specify default kexec and crash kernel ops, thus effectively adds a working kexec support for most boards.

Platforms that can't cope with default ops will explode in some weird way (a hang or reboot is most likely), which means that the board's kexec support should be fixed or blacklisted via dummy _prepare callback returning -ENOSYS.

Quoted 5 lines
Quoted 1 line

But where is the patch to do this?

The -ENOSYS dummy callback is a last resort thing to do when nobody cares or it's impossible to fix the Kexec on some board. We don't have any such boards (yet).

Yes we do, iseries, so at the very least we need a patch for that.

Quoted 11 lines
Quoted 3 lines

The chance of kexec working on some random machine that's never been tested is pretty slim, every driver needs to be aware its hardware might be in a weird state,

The boards setup isn't always static. The Kexec might work perfectly well on a standalone board, but might hang with some weird PCI device attached to it (think that it might need some PCI fixup on shutdown).

I think that a "Kexec tested to work on a particular board" term just doesn't exist. It might work, but it might hang with other setup on the *same* board.

Sure, nothing is 100%, I'd just rather that someone has at least tried a kexec on the basic config and had it work.

Quoted 4 lines

But in practice the Kexec work on every 6xx board I have. And I have pretty much of Freescale boards (almost all from the 83xx series), and I don't think it's practical to add #ifdef CONFIG_KEXEC into the every board file...

OK in that case I'm OK with it. The Kconfig restricts it to only PPC64 or 6xx, so it's not enabled on _every_ platform.

cheers

Signature · 8 lines
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
#6 lore raw

PATCH 3/3 powerpc: Remove default kexec/crash_kernel ops assignments

In reply to Anton Vorontsov

Default ops are implicit now.

---
 arch/powerpc/platforms/cell/celleb_setup.c     |    9 ---------
 arch/powerpc/platforms/cell/setup.c            |    6 ------
 arch/powerpc/platforms/embedded6xx/c2k.c       |    6 ------
 arch/powerpc/platforms/embedded6xx/prpmc2800.c |    6 ------
 arch/powerpc/platforms/maple/setup.c           |    6 ------
 arch/powerpc/platforms/powermac/setup.c        |    6 ------
 arch/powerpc/platforms/ps3/setup.c             |    4 ----
 7 files changed, 0 insertions(+), 43 deletions(-)
arch/powerpc/platforms/cell/celleb_setup.c +0 -9
index b11cb30..07c234f 100644
@@ -45,7 +45,6 @@
 #include <asm/mmu.h>
 #include <asm/processor.h>
 #include <asm/io.h>
-#include <asm/kexec.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/cputable.h>
@@ -226,9 +225,6 @@ define_machine(celleb_beat) {
 	.pci_setup_phb		= celleb_setup_phb,
 #ifdef CONFIG_KEXEC
 	.kexec_cpu_down		= beat_kexec_cpu_down,
-	.machine_kexec		= default_machine_kexec,
-	.machine_kexec_prepare	= default_machine_kexec_prepare,
-	.machine_crash_shutdown	= default_machine_crash_shutdown,
 #endif
 };
 
@@ -248,9 +244,4 @@ define_machine(celleb_native) {
 	.pci_probe_mode 	= celleb_pci_probe_mode,
 	.pci_setup_phb		= celleb_setup_phb,
 	.init_IRQ		= celleb_init_IRQ_native,
-#ifdef CONFIG_KEXEC
-	.machine_kexec		= default_machine_kexec,
-	.machine_kexec_prepare	= default_machine_kexec_prepare,
-	.machine_crash_shutdown	= default_machine_crash_shutdown,
-#endif
 };
arch/powerpc/platforms/cell/setup.c +0 -6
index ab721b5..5930536 100644
@@ -35,7 +35,6 @@
 #include <asm/mmu.h>
 #include <asm/processor.h>
 #include <asm/io.h>
-#include <asm/kexec.h>
 #include <asm/pgtable.h>
 #include <asm/prom.h>
 #include <asm/rtas.h>
@@ -289,9 +288,4 @@ define_machine(cell) {
 	.progress		= cell_progress,
 	.init_IRQ       	= cell_init_irq,
 	.pci_setup_phb		= cell_setup_phb,
-#ifdef CONFIG_KEXEC
-	.machine_kexec		= default_machine_kexec,
-	.machine_kexec_prepare	= default_machine_kexec_prepare,
-	.machine_crash_shutdown	= default_machine_crash_shutdown,
-#endif
 };
arch/powerpc/platforms/embedded6xx/c2k.c +0 -6
index 32ba0fa..8cab573 100644
@@ -20,7 +20,6 @@
 #include <linux/seq_file.h>
 #include <linux/time.h>
 #include <linux/of.h>
-#include <linux/kexec.h>
 
 #include <asm/machdep.h>
 #include <asm/prom.h>
@@ -147,9 +146,4 @@ define_machine(c2k) {
 	.get_irq		= mv64x60_get_irq,
 	.restart		= c2k_restart,
 	.calibrate_decr		= generic_calibrate_decr,
-#ifdef CONFIG_KEXEC
-	.machine_kexec		= default_machine_kexec,
-	.machine_kexec_prepare	= default_machine_kexec_prepare,
-	.machine_crash_shutdown	= default_machine_crash_shutdown,
-#endif
 };
arch/powerpc/platforms/embedded6xx/prpmc2800.c +0 -6
index 4c485e9..670035f 100644
@@ -19,7 +19,6 @@
 #include <asm/prom.h>
 #include <asm/system.h>
 #include <asm/time.h>
-#include <asm/kexec.h>
 
 #include <mm/mmu_decl.h>
 
@@ -155,9 +154,4 @@ define_machine(prpmc2800){
 	.get_irq		= mv64x60_get_irq,
 	.restart		= prpmc2800_restart,
 	.calibrate_decr		= generic_calibrate_decr,
-#ifdef CONFIG_KEXEC
-	.machine_kexec		= default_machine_kexec,
-	.machine_kexec_prepare	= default_machine_kexec_prepare,
-	.machine_crash_shutdown	= default_machine_crash_shutdown,
-#endif
 };
arch/powerpc/platforms/maple/setup.c +0 -6
index d4c61c3..bfd60e4 100644
@@ -50,7 +50,6 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/kexec.h>
 #include <asm/pci-bridge.h>
 #include <asm/iommu.h>
 #include <asm/machdep.h>
@@ -335,9 +334,4 @@ define_machine(maple) {
       	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= maple_progress,
 	.power_save		= power4_idle,
-#ifdef CONFIG_KEXEC
-	.machine_kexec		= default_machine_kexec,
-	.machine_kexec_prepare	= default_machine_kexec_prepare,
-	.machine_crash_shutdown	= default_machine_crash_shutdown,
-#endif
 };
arch/powerpc/platforms/powermac/setup.c +0 -6
index 1293772..9b78f53 100644
@@ -60,7 +60,6 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/kexec.h>
 #include <asm/pci-bridge.h>
 #include <asm/ohare.h>
 #include <asm/mediabay.h>
@@ -738,11 +737,6 @@ define_machine(powermac) {
 	.pci_probe_mode		= pmac_pci_probe_mode,
 	.power_save		= power4_idle,
 	.enable_pmcs		= power4_enable_pmcs,
-#ifdef CONFIG_KEXEC
-	.machine_kexec		= default_machine_kexec,
-	.machine_kexec_prepare	= default_machine_kexec_prepare,
-	.machine_crash_shutdown	= default_machine_crash_shutdown,
-#endif
 #endif /* CONFIG_PPC64 */
 #ifdef CONFIG_PPC32
 	.pcibios_enable_device_hook = pmac_pci_enable_device_hook,
arch/powerpc/platforms/ps3/setup.c +0 -4
index bfc33fb..35f3e85 100644
@@ -23,7 +23,6 @@
 #include <linux/fs.h>
 #include <linux/root_dev.h>
 #include <linux/console.h>
-#include <linux/kexec.h>
 #include <linux/bootmem.h>
 
 #include <asm/machdep.h>
@@ -281,8 +280,5 @@ define_machine(ps3) {
 	.halt				= ps3_halt,
 #if defined(CONFIG_KEXEC)
 	.kexec_cpu_down			= ps3_kexec_cpu_down,
-	.machine_kexec			= default_machine_kexec,
-	.machine_kexec_prepare		= default_machine_kexec_prepare,
-	.machine_crash_shutdown		= default_machine_crash_shutdown,
 #endif
 };
Signature · 1 line
1.5.6.5