[PATCH 0/8]: Some kexec/kdump cleanups

STALE5700d

10 messages, 1 author, 2011-01-21 · open the first message on its own page

[PATCH 0/8]: Some kexec/kdump cleanups

From: Anton Blanchard <hidden>
Date: 2011-01-07 03:52:55

Hi,

These patches have been sitting around in my tree for a while. Back
when I was trying to understand the twisty maze of powerpc kexec/kdump
I did a number of cleanups. Here they are.

Anton

[PATCH 1/8] powerpc: Move all ppc_md kexec function pointers together

From: Anton Blanchard <hidden>
Date: 2011-01-07 03:54:15

Move all the kexec handlers together.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/include/asm/machdep.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/machdep.h	2011-01-07 12:50:52.020438276 +1100
+++ powerpc.git/arch/powerpc/include/asm/machdep.h	2011-01-07 12:51:46.682161055 +1100
@@ -118,9 +118,6 @@ struct machdep_calls {
 	 * If for some reason there is no irq, but the interrupt
 	 * shouldn't be counted as spurious, return NO_IRQ_IGNORE. */
 	unsigned int	(*get_irq)(void);
-#ifdef CONFIG_KEXEC
-	void		(*kexec_cpu_down)(int crash_shutdown, int secondary);
-#endif
 
 	/* PCI stuff */
 	/* Called after scanning the bus, before allocating resources */
@@ -237,6 +234,8 @@ struct machdep_calls {
 	void (*machine_shutdown)(void);
 
 #ifdef CONFIG_KEXEC
+	void (*kexec_cpu_down)(int crash_shutdown, int secondary);
+
 	/* Called to do the minimal shutdown needed to run a kexec'd kernel
 	 * to run successfully.
 	 * XXX Should we move this one out of kexec scope?

[PATCH 2/8] powerpc/kexec: Remove ppc_md.machine_kexec_cleanup

From: Anton Blanchard <hidden>
Date: 2011-01-07 03:54:58

No one uses ppc_md.machine_kexec_cleanup, so remove it.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/include/asm/machdep.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/machdep.h	2011-01-07 12:51:46.682161055 +1100
+++ powerpc.git/arch/powerpc/include/asm/machdep.h	2011-01-07 12:51:51.352308248 +1100
@@ -249,9 +249,6 @@ struct machdep_calls {
 	 */
 	int (*machine_kexec_prepare)(struct kimage *image);
 
-	/* Called to handle any machine specific cleanup on image */
-	void (*machine_kexec_cleanup)(struct kimage *image);
-
 	/* Called to perform the _real_ kexec.
 	 * Do NOT allocate memory or fail here. We are past the point of
 	 * no return.
Index: powerpc.git/arch/powerpc/kernel/machine_kexec.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/machine_kexec.c	2010-12-13 22:52:03.975251680 +1100
+++ powerpc.git/arch/powerpc/kernel/machine_kexec.c	2011-01-07 12:51:51.352308248 +1100
@@ -65,8 +65,6 @@ int machine_kexec_prepare(struct kimage
 
 void machine_kexec_cleanup(struct kimage *image)
 {
-	if (ppc_md.machine_kexec_cleanup)
-		ppc_md.machine_kexec_cleanup(image);
 }
 
 void arch_crash_save_vmcoreinfo(void)

[PATCH 3/8] powerpc/kexec: Remove ppc_md.machine_kexec

From: Anton Blanchard <hidden>
Date: 2011-01-07 03:55:36

No one uses ppc_md.machine_kexec, so remove it.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/include/asm/machdep.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/machdep.h	2011-01-07 12:51:51.352308248 +1100
+++ powerpc.git/arch/powerpc/include/asm/machdep.h	2011-01-07 12:51:54.082394288 +1100
@@ -248,12 +248,6 @@ struct machdep_calls {
 	 * claims to support kexec.
 	 */
 	int (*machine_kexec_prepare)(struct kimage *image);
-
-	/* Called to perform the _real_ kexec.
-	 * Do NOT allocate memory or fail here. We are past the point of
-	 * no return.
-	 */
-	void (*machine_kexec)(struct kimage *image);
 #endif /* CONFIG_KEXEC */
 
 #ifdef CONFIG_SUSPEND
Index: powerpc.git/arch/powerpc/kernel/machine_kexec.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/machine_kexec.c	2011-01-07 12:51:51.352308248 +1100
+++ powerpc.git/arch/powerpc/kernel/machine_kexec.c	2011-01-07 12:51:54.082394288 +1100
@@ -85,10 +85,7 @@ void arch_crash_save_vmcoreinfo(void)
  */
 void machine_kexec(struct kimage *image)
 {
-	if (ppc_md.machine_kexec)
-		ppc_md.machine_kexec(image);
-	else
-		default_machine_kexec(image);
+	default_machine_kexec(image);
 
 	/* Fall back to normal restart if we're still alive. */
 	machine_restart(NULL);

[PATCH 4/8] powerpc/kdump: Remove ppc_md.machine_crash_shutdown

From: Anton Blanchard <hidden>
Date: 2011-01-07 03:56:09

No one uses ppc_md.machine_crash_shutdown, so remove it.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/include/asm/machdep.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/machdep.h	2011-01-07 12:51:54.082394288 +1100
+++ powerpc.git/arch/powerpc/include/asm/machdep.h	2011-01-07 12:51:56.222461754 +1100
@@ -236,12 +236,6 @@ struct machdep_calls {
 #ifdef CONFIG_KEXEC
 	void (*kexec_cpu_down)(int crash_shutdown, int secondary);
 
-	/* Called to do the minimal shutdown needed to run a kexec'd kernel
-	 * to run successfully.
-	 * XXX Should we move this one out of kexec scope?
-	 */
-	void (*machine_crash_shutdown)(struct pt_regs *regs);
-
 	/* Called to do what every setup is needed on image and the
 	 * reboot code buffer. Returns 0 on success.
 	 * Provide your own (maybe dummy) implementation if your platform
Index: powerpc.git/arch/powerpc/kernel/machine_kexec.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/machine_kexec.c	2011-01-07 12:51:54.082394288 +1100
+++ powerpc.git/arch/powerpc/kernel/machine_kexec.c	2011-01-07 12:51:56.222461754 +1100
@@ -44,10 +44,7 @@ void machine_kexec_mask_interrupts(void)
 
 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);
+	default_machine_crash_shutdown(regs);
 }
 
 /*
Index: powerpc.git/arch/powerpc/platforms/cell/qpace_setup.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/qpace_setup.c	2010-12-13 22:52:03.765247709 +1100
+++ powerpc.git/arch/powerpc/platforms/cell/qpace_setup.c	2011-01-07 12:51:56.222461754 +1100
@@ -148,6 +148,5 @@ define_machine(qpace) {
 #ifdef CONFIG_KEXEC
 	.machine_kexec		= default_machine_kexec,
 	.machine_kexec_prepare	= default_machine_kexec_prepare,
-	.machine_crash_shutdown	= default_machine_crash_shutdown,
 #endif
 };
Index: powerpc.git/arch/powerpc/platforms/pseries/kexec.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/pseries/kexec.c	2010-12-13 22:52:03.745247341 +1100
+++ powerpc.git/arch/powerpc/platforms/pseries/kexec.c	2011-01-07 12:51:56.222461754 +1100
@@ -66,7 +66,6 @@ static int __init pseries_kexec_setup(vo
 {
 	ppc_md.machine_kexec = default_machine_kexec;
 	ppc_md.machine_kexec_prepare = default_machine_kexec_prepare;
-	ppc_md.machine_crash_shutdown = default_machine_crash_shutdown;
 
 	return 0;
 }

[PATCH 5/8] powerpc/kexec: Don't initialise kexec hooks to default handlers

From: Anton Blanchard <hidden>
Date: 2011-01-07 03:57:03

There's no need to initialise ppc_md.machine_kexec and
ppc_md.machine_kexec_prepare to the default handlers.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/platforms/cell/qpace_setup.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/qpace_setup.c	2011-01-07 12:51:56.222461754 +1100
+++ powerpc.git/arch/powerpc/platforms/cell/qpace_setup.c	2011-01-07 12:51:58.112521318 +1100
@@ -145,8 +145,4 @@ define_machine(qpace) {
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= qpace_progress,
 	.init_IRQ		= iic_init_IRQ,
-#ifdef CONFIG_KEXEC
-	.machine_kexec		= default_machine_kexec,
-	.machine_kexec_prepare	= default_machine_kexec_prepare,
-#endif
 };
Index: powerpc.git/arch/powerpc/platforms/pseries/kexec.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/pseries/kexec.c	2011-01-07 12:51:56.222461754 +1100
+++ powerpc.git/arch/powerpc/platforms/pseries/kexec.c	2011-01-07 12:51:58.112521318 +1100
@@ -61,12 +61,3 @@ void __init setup_kexec_cpu_down_xics(vo
 {
 	ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_xics;
 }
-
-static int __init pseries_kexec_setup(void)
-{
-	ppc_md.machine_kexec = default_machine_kexec;
-	ppc_md.machine_kexec_prepare = default_machine_kexec_prepare;
-
-	return 0;
-}
-machine_device_initcall(pseries, pseries_kexec_setup);

[PATCH 6/8] powerpc/kexec: Remove empty ppc_md.machine_kexec_prepare

From: Anton Blanchard <hidden>
Date: 2011-01-07 03:58:36

We check for a valid handler before calling ppc_md.machine_kexec_prepare
so we can just remove these empty handlers.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/platforms/embedded6xx/wii.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/embedded6xx/wii.c	2010-12-13 22:52:03.535243386 +1100
+++ powerpc.git/arch/powerpc/platforms/embedded6xx/wii.c	2011-01-07 12:51:59.422562597 +1100
@@ -18,7 +18,6 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/seq_file.h>
-#include <linux/kexec.h>
 #include <linux/of_platform.h>
 #include <linux/memblock.h>
 #include <mm/mmu_decl.h>
@@ -226,13 +225,6 @@ static void wii_shutdown(void)
 	flipper_quiesce();
 }
 
-#ifdef CONFIG_KEXEC
-static int wii_machine_kexec_prepare(struct kimage *image)
-{
-	return 0;
-}
-#endif /* CONFIG_KEXEC */
-
 define_machine(wii) {
 	.name			= "wii",
 	.probe			= wii_probe,
@@ -246,9 +238,6 @@ define_machine(wii) {
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
 	.machine_shutdown	= wii_shutdown,
-#ifdef CONFIG_KEXEC
-	.machine_kexec_prepare	= wii_machine_kexec_prepare,
-#endif
 };
 
 static struct of_device_id wii_of_bus[] = {
Index: powerpc.git/arch/powerpc/platforms/embedded6xx/gamecube.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/embedded6xx/gamecube.c	2010-12-13 22:52:03.555243746 +1100
+++ powerpc.git/arch/powerpc/platforms/embedded6xx/gamecube.c	2011-01-07 12:51:59.422562597 +1100
@@ -75,14 +75,6 @@ static void gamecube_shutdown(void)
 	flipper_quiesce();
 }
 
-#ifdef CONFIG_KEXEC
-static int gamecube_kexec_prepare(struct kimage *image)
-{
-	return 0;
-}
-#endif /* CONFIG_KEXEC */
-
-
 define_machine(gamecube) {
 	.name			= "gamecube",
 	.probe			= gamecube_probe,
@@ -95,9 +87,6 @@ define_machine(gamecube) {
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
 	.machine_shutdown	= gamecube_shutdown,
-#ifdef CONFIG_KEXEC
-	.machine_kexec_prepare	= gamecube_kexec_prepare,
-#endif
 };
 
 

[PATCH 7/8] powerpc/kdump: Move crash_kexec_stop_spus to kdump crash handler

From: Anton Blanchard <hidden>
Date: 2011-01-07 03:59:54

Use the crash handler hooks to run the SPU stop code, just like we do for
ehea and cell RAS code.

While I'm here I noticed "CPUSs reliabally"

so fix the spelling MISTAKESs reliabally.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/kernel/crash.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/crash.c	2010-12-13 22:52:03.475242242 +1100
+++ powerpc.git/arch/powerpc/kernel/crash.c	2011-01-07 12:52:00.812606428 +1100
@@ -48,7 +48,7 @@ int crashing_cpu = -1;
 static cpumask_t cpus_in_crash = CPU_MASK_NONE;
 cpumask_t cpus_in_sr = CPU_MASK_NONE;
 
-#define CRASH_HANDLER_MAX 2
+#define CRASH_HANDLER_MAX 3
 /* NULL terminated list of shutdown handles */
 static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX+1];
 static DEFINE_SPINLOCK(crash_handlers_lock);
@@ -125,7 +125,7 @@ static void crash_kexec_prepare_cpus(int
 	smp_wmb();
 
 	/*
-	 * FIXME: Until we will have the way to stop other CPUSs reliabally,
+	 * FIXME: Until we will have the way to stop other CPUs reliably,
 	 * the crash CPU will send an IPI and wait for other CPUs to
 	 * respond.
 	 * Delay of at least 10 seconds.
@@ -254,72 +254,6 @@ void crash_kexec_secondary(struct pt_reg
 	cpus_in_sr = CPU_MASK_NONE;
 }
 #endif
-#ifdef CONFIG_SPU_BASE
-
-#include <asm/spu.h>
-#include <asm/spu_priv1.h>
-
-struct crash_spu_info {
-	struct spu *spu;
-	u32 saved_spu_runcntl_RW;
-	u32 saved_spu_status_R;
-	u32 saved_spu_npc_RW;
-	u64 saved_mfc_sr1_RW;
-	u64 saved_mfc_dar;
-	u64 saved_mfc_dsisr;
-};
-
-#define CRASH_NUM_SPUS	16	/* Enough for current hardware */
-static struct crash_spu_info crash_spu_info[CRASH_NUM_SPUS];
-
-static void crash_kexec_stop_spus(void)
-{
-	struct spu *spu;
-	int i;
-	u64 tmp;
-
-	for (i = 0; i < CRASH_NUM_SPUS; i++) {
-		if (!crash_spu_info[i].spu)
-			continue;
-
-		spu = crash_spu_info[i].spu;
-
-		crash_spu_info[i].saved_spu_runcntl_RW =
-			in_be32(&spu->problem->spu_runcntl_RW);
-		crash_spu_info[i].saved_spu_status_R =
-			in_be32(&spu->problem->spu_status_R);
-		crash_spu_info[i].saved_spu_npc_RW =
-			in_be32(&spu->problem->spu_npc_RW);
-
-		crash_spu_info[i].saved_mfc_dar    = spu_mfc_dar_get(spu);
-		crash_spu_info[i].saved_mfc_dsisr  = spu_mfc_dsisr_get(spu);
-		tmp = spu_mfc_sr1_get(spu);
-		crash_spu_info[i].saved_mfc_sr1_RW = tmp;
-
-		tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
-		spu_mfc_sr1_set(spu, tmp);
-
-		__delay(200);
-	}
-}
-
-void crash_register_spus(struct list_head *list)
-{
-	struct spu *spu;
-
-	list_for_each_entry(spu, list, full_list) {
-		if (WARN_ON(spu->number >= CRASH_NUM_SPUS))
-			continue;
-
-		crash_spu_info[spu->number].spu = spu;
-	}
-}
-
-#else
-static inline void crash_kexec_stop_spus(void)
-{
-}
-#endif /* CONFIG_SPU_BASE */
 
 /*
  * Register a function to be called on shutdown.  Only use this if you
@@ -439,8 +373,6 @@ void default_machine_crash_shutdown(stru
 	crash_shutdown_cpu = -1;
 	__debugger_fault_handler = old_handler;
 
-	crash_kexec_stop_spus();
-
 	if (ppc_md.kexec_cpu_down)
 		ppc_md.kexec_cpu_down(1, 0);
 }
Index: powerpc.git/arch/powerpc/platforms/cell/spu_base.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/spu_base.c	2010-12-13 22:52:03.495242622 +1100
+++ powerpc.git/arch/powerpc/platforms/cell/spu_base.c	2011-01-07 12:52:00.812606428 +1100
@@ -727,6 +727,67 @@ static ssize_t spu_stat_show(struct sys_
 
 static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
 
+struct crash_spu_info {
+	struct spu *spu;
+	u32 saved_spu_runcntl_RW;
+	u32 saved_spu_status_R;
+	u32 saved_spu_npc_RW;
+	u64 saved_mfc_sr1_RW;
+	u64 saved_mfc_dar;
+	u64 saved_mfc_dsisr;
+};
+
+#define CRASH_NUM_SPUS	16	/* Enough for current hardware */
+static struct crash_spu_info crash_spu_info[CRASH_NUM_SPUS];
+
+static void crash_kexec_stop_spus(void)
+{
+	struct spu *spu;
+	int i;
+	u64 tmp;
+
+	for (i = 0; i < CRASH_NUM_SPUS; i++) {
+		if (!crash_spu_info[i].spu)
+			continue;
+
+		spu = crash_spu_info[i].spu;
+
+		crash_spu_info[i].saved_spu_runcntl_RW =
+			in_be32(&spu->problem->spu_runcntl_RW);
+		crash_spu_info[i].saved_spu_status_R =
+			in_be32(&spu->problem->spu_status_R);
+		crash_spu_info[i].saved_spu_npc_RW =
+			in_be32(&spu->problem->spu_npc_RW);
+
+		crash_spu_info[i].saved_mfc_dar    = spu_mfc_dar_get(spu);
+		crash_spu_info[i].saved_mfc_dsisr  = spu_mfc_dsisr_get(spu);
+		tmp = spu_mfc_sr1_get(spu);
+		crash_spu_info[i].saved_mfc_sr1_RW = tmp;
+
+		tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
+		spu_mfc_sr1_set(spu, tmp);
+
+		__delay(200);
+	}
+}
+
+static void crash_register_spus(struct list_head *list)
+{
+	struct spu *spu;
+	int ret;
+
+	list_for_each_entry(spu, list, full_list) {
+		if (WARN_ON(spu->number >= CRASH_NUM_SPUS))
+			continue;
+
+		crash_spu_info[spu->number].spu = spu;
+	}
+
+	ret = crash_shutdown_register(&crash_kexec_stop_spus);
+	if (ret)
+		printk(KERN_ERR "Could not register SPU crash handler");
+}
+
 static int __init init_spu_base(void)
 {
 	int i, ret = 0;

[PATCH 8/8] powerpc/kdump: Disable ftrace during kexec

From: Anton Blanchard <hidden>
Date: 2011-01-07 04:00:36

We should disable ftrace during kexec, some of the tracers are very invasive
and we do not want them going off while doing the low level work of swapping
one kernel out for another. This mirrors what we do on x86.

Even though we cannot return from a kexec on powerpc (since we do not implement
CONFIG_KEXEC_JUMP), add the restore code in case we do one day.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/kernel/machine_kexec.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/machine_kexec.c	2011-01-07 12:51:56.222461754 +1100
+++ powerpc.git/arch/powerpc/kernel/machine_kexec.c	2011-01-07 12:52:02.012644243 +1100
@@ -15,6 +15,7 @@
 #include <linux/memblock.h>
 #include <linux/of.h>
 #include <linux/irq.h>
+#include <linux/ftrace.h>
 
 #include <asm/machdep.h>
 #include <asm/prom.h>
@@ -82,8 +83,14 @@ void arch_crash_save_vmcoreinfo(void)
  */
 void machine_kexec(struct kimage *image)
 {
+	int save_ftrace_enabled;
+
+	save_ftrace_enabled = __ftrace_enabled_save();
+
 	default_machine_kexec(image);
 
+	__ftrace_enabled_restore(save_ftrace_enabled);
+
 	/* Fall back to normal restart if we're still alive. */
 	machine_restart(NULL);
 	for(;;);

[PATCH 7/8] powerpc/kdump: Move crash_kexec_stop_spus to kdump crash handler

From: Anton Blanchard <hidden>
Date: 2011-01-21 02:43:59

And here's a version that actually compiles. Sorry Ben :)

Anton
--

Use the crash handler hooks to run the SPU stop code, just like we do for
ehea and cell RAS code.

While I'm here I noticed "CPUSs reliabally"

so fix the spelling MISTAKESs reliabally.

Signed-off-by: Anton Blanchard <redacted>
---

Index: powerpc.git/arch/powerpc/kernel/crash.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/crash.c	2011-01-21 13:41:01.192747292 +1100
+++ powerpc.git/arch/powerpc/kernel/crash.c	2011-01-21 13:41:07.272364454 +1100
@@ -48,7 +48,7 @@ int crashing_cpu = -1;
 static cpumask_t cpus_in_crash = CPU_MASK_NONE;
 cpumask_t cpus_in_sr = CPU_MASK_NONE;
 
-#define CRASH_HANDLER_MAX 2
+#define CRASH_HANDLER_MAX 3
 /* NULL terminated list of shutdown handles */
 static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX+1];
 static DEFINE_SPINLOCK(crash_handlers_lock);
@@ -125,7 +125,7 @@ static void crash_kexec_prepare_cpus(int
 	smp_wmb();
 
 	/*
-	 * FIXME: Until we will have the way to stop other CPUSs reliabally,
+	 * FIXME: Until we will have the way to stop other CPUs reliably,
 	 * the crash CPU will send an IPI and wait for other CPUs to
 	 * respond.
 	 * Delay of at least 10 seconds.
@@ -254,72 +254,6 @@ void crash_kexec_secondary(struct pt_reg
 	cpus_in_sr = CPU_MASK_NONE;
 }
 #endif
-#ifdef CONFIG_SPU_BASE
-
-#include <asm/spu.h>
-#include <asm/spu_priv1.h>
-
-struct crash_spu_info {
-	struct spu *spu;
-	u32 saved_spu_runcntl_RW;
-	u32 saved_spu_status_R;
-	u32 saved_spu_npc_RW;
-	u64 saved_mfc_sr1_RW;
-	u64 saved_mfc_dar;
-	u64 saved_mfc_dsisr;
-};
-
-#define CRASH_NUM_SPUS	16	/* Enough for current hardware */
-static struct crash_spu_info crash_spu_info[CRASH_NUM_SPUS];
-
-static void crash_kexec_stop_spus(void)
-{
-	struct spu *spu;
-	int i;
-	u64 tmp;
-
-	for (i = 0; i < CRASH_NUM_SPUS; i++) {
-		if (!crash_spu_info[i].spu)
-			continue;
-
-		spu = crash_spu_info[i].spu;
-
-		crash_spu_info[i].saved_spu_runcntl_RW =
-			in_be32(&spu->problem->spu_runcntl_RW);
-		crash_spu_info[i].saved_spu_status_R =
-			in_be32(&spu->problem->spu_status_R);
-		crash_spu_info[i].saved_spu_npc_RW =
-			in_be32(&spu->problem->spu_npc_RW);
-
-		crash_spu_info[i].saved_mfc_dar    = spu_mfc_dar_get(spu);
-		crash_spu_info[i].saved_mfc_dsisr  = spu_mfc_dsisr_get(spu);
-		tmp = spu_mfc_sr1_get(spu);
-		crash_spu_info[i].saved_mfc_sr1_RW = tmp;
-
-		tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
-		spu_mfc_sr1_set(spu, tmp);
-
-		__delay(200);
-	}
-}
-
-void crash_register_spus(struct list_head *list)
-{
-	struct spu *spu;
-
-	list_for_each_entry(spu, list, full_list) {
-		if (WARN_ON(spu->number >= CRASH_NUM_SPUS))
-			continue;
-
-		crash_spu_info[spu->number].spu = spu;
-	}
-}
-
-#else
-static inline void crash_kexec_stop_spus(void)
-{
-}
-#endif /* CONFIG_SPU_BASE */
 
 /*
  * Register a function to be called on shutdown.  Only use this if you
@@ -439,8 +373,6 @@ void default_machine_crash_shutdown(stru
 	crash_shutdown_cpu = -1;
 	__debugger_fault_handler = old_handler;
 
-	crash_kexec_stop_spus();
-
 	if (ppc_md.kexec_cpu_down)
 		ppc_md.kexec_cpu_down(1, 0);
 }
Index: powerpc.git/arch/powerpc/platforms/cell/spu_base.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/spu_base.c	2011-01-21 13:41:01.192747292 +1100
+++ powerpc.git/arch/powerpc/platforms/cell/spu_base.c	2011-01-21 13:42:12.358265951 +1100
@@ -37,6 +37,7 @@
 #include <asm/spu_csa.h>
 #include <asm/xmon.h>
 #include <asm/prom.h>
+#include <asm/kexec.h>
 
 const struct spu_management_ops *spu_management_ops;
 EXPORT_SYMBOL_GPL(spu_management_ops);
@@ -727,6 +728,75 @@ static ssize_t spu_stat_show(struct sys_
 
 static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
 
+#ifdef CONFIG_KEXEC
+
+struct crash_spu_info {
+	struct spu *spu;
+	u32 saved_spu_runcntl_RW;
+	u32 saved_spu_status_R;
+	u32 saved_spu_npc_RW;
+	u64 saved_mfc_sr1_RW;
+	u64 saved_mfc_dar;
+	u64 saved_mfc_dsisr;
+};
+
+#define CRASH_NUM_SPUS	16	/* Enough for current hardware */
+static struct crash_spu_info crash_spu_info[CRASH_NUM_SPUS];
+
+static void crash_kexec_stop_spus(void)
+{
+	struct spu *spu;
+	int i;
+	u64 tmp;
+
+	for (i = 0; i < CRASH_NUM_SPUS; i++) {
+		if (!crash_spu_info[i].spu)
+			continue;
+
+		spu = crash_spu_info[i].spu;
+
+		crash_spu_info[i].saved_spu_runcntl_RW =
+			in_be32(&spu->problem->spu_runcntl_RW);
+		crash_spu_info[i].saved_spu_status_R =
+			in_be32(&spu->problem->spu_status_R);
+		crash_spu_info[i].saved_spu_npc_RW =
+			in_be32(&spu->problem->spu_npc_RW);
+
+		crash_spu_info[i].saved_mfc_dar    = spu_mfc_dar_get(spu);
+		crash_spu_info[i].saved_mfc_dsisr  = spu_mfc_dsisr_get(spu);
+		tmp = spu_mfc_sr1_get(spu);
+		crash_spu_info[i].saved_mfc_sr1_RW = tmp;
+
+		tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
+		spu_mfc_sr1_set(spu, tmp);
+
+		__delay(200);
+	}
+}
+
+static void crash_register_spus(struct list_head *list)
+{
+	struct spu *spu;
+	int ret;
+
+	list_for_each_entry(spu, list, full_list) {
+		if (WARN_ON(spu->number >= CRASH_NUM_SPUS))
+			continue;
+
+		crash_spu_info[spu->number].spu = spu;
+	}
+
+	ret = crash_shutdown_register(&crash_kexec_stop_spus);
+	if (ret)
+		printk(KERN_ERR "Could not register SPU crash handler");
+}
+
+#else
+static inline void crash_register_spus(struct list_head *list)
+{
+}
+#endif
+
 static int __init init_spu_base(void)
 {
 	int i, ret = 0;
Index: powerpc.git/arch/powerpc/include/asm/spu.h
===================================================================
--- powerpc.git.orig/arch/powerpc/include/asm/spu.h	2011-01-21 13:41:00.592785080 +1100
+++ powerpc.git/arch/powerpc/include/asm/spu.h	2011-01-21 13:42:12.358265951 +1100
@@ -203,14 +203,6 @@ void spu_irq_setaffinity(struct spu *spu
 void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
 		void *code, int code_size);
 
-#ifdef CONFIG_KEXEC
-void crash_register_spus(struct list_head *list);
-#else
-static inline void crash_register_spus(struct list_head *list)
-{
-}
-#endif
-
 extern void spu_invalidate_slbs(struct spu *spu);
 extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm);
 int spu_64k_pages_available(void);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help