[PATCH 8/12] powerpc: Turn cpu_irq_down into kexec_cpu_down

Michael Ellerman michael at ellerman.id.au
Tue Nov 8 00:07:05 EST 2005


We currently have a ppc_md member called cpu_irq_down, which disables IRQs
for the cpu in question. The only caller of cpu_irq_down is the kexec code.

On pSeries we need to do more than just teardown IRQs at kexec time, so rename
the ppc_md member to kexec_cpu_down and expand it. The pSeries code needs to
know, and other platforms might too, whether we're doing a crash shutdown (ie.
panicking) or a regular kexec, so add a flag for that.

 arch/powerpc/platforms/pseries/setup.c |   26 ++++++++++++++++++++++++--
 arch/ppc64/kernel/machine_kexec.c      |   12 ++++++------
 include/asm-powerpc/machdep.h          |    4 +++-
 3 files changed, 33 insertions(+), 9 deletions(-)

Index: kexec/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- kexec.orig/arch/powerpc/platforms/pseries/setup.c
+++ kexec/arch/powerpc/platforms/pseries/setup.c
@@ -200,14 +200,12 @@ static void __init pSeries_setup_arch(vo
 	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
 		ppc_md.init_IRQ       = pSeries_init_mpic;
 		ppc_md.get_irq        = mpic_get_irq;
-	 	ppc_md.cpu_irq_down   = mpic_teardown_this_cpu;
 		/* Allocate the mpic now, so that find_and_init_phbs() can
 		 * fill the ISUs */
 		pSeries_setup_mpic();
 	} else {
 		ppc_md.init_IRQ       = xics_init_IRQ;
 		ppc_md.get_irq        = xics_get_irq;
-		ppc_md.cpu_irq_down   = xics_teardown_cpu;
 	}
 
 #ifdef CONFIG_SMP
@@ -597,6 +595,27 @@ static int pSeries_pci_probe_mode(struct
 	return PCI_PROBE_NORMAL;
 }
 
+#ifdef CONFIG_KEXEC
+static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
+{
+	/* Don't risk a hypervisor call if we're crashing */
+	if (!crash_shutdown) {
+		unsigned long vpa = __pa(&get_paca()->lppaca);
+
+		if (unregister_vpa(hard_smp_processor_id(), vpa)) {
+			printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
+					"failed\n", smp_processor_id(),
+					hard_smp_processor_id());
+		}
+	}
+
+	if (ppc64_interrupt_controller == IC_OPEN_PIC)
+		mpic_teardown_this_cpu(secondary);
+	else
+		xics_teardown_cpu(secondary);
+}
+#endif
+
 struct machdep_calls __initdata pSeries_md = {
 	.probe			= pSeries_probe,
 	.setup_arch		= pSeries_setup_arch,
@@ -619,4 +638,7 @@ struct machdep_calls __initdata pSeries_
 	.check_legacy_ioport	= pSeries_check_legacy_ioport,
 	.system_reset_exception = pSeries_system_reset_exception,
 	.machine_check_exception = pSeries_machine_check_exception,
+#ifdef CONFIG_KEXEC
+	.kexec_cpu_down		= pseries_kexec_cpu_down,
+#endif
 };
Index: kexec/arch/ppc64/kernel/machine_kexec.c
===================================================================
--- kexec.orig/arch/ppc64/kernel/machine_kexec.c
+++ kexec/arch/ppc64/kernel/machine_kexec.c
@@ -169,8 +169,8 @@ void kexec_copy_flush(struct kimage *ima
  */
 void kexec_smp_down(void *arg)
 {
-	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down(1);
+	if (ppc_md.kexec_cpu_down)
+		ppc_md.kexec_cpu_down(0, 1);
 
 	local_irq_disable();
 	kexec_smp_wait();
@@ -217,8 +217,8 @@ static void kexec_prepare_cpus(void)
 	}
 
 	/* after we tell the others to go down */
-	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down(0);
+	if (ppc_md.kexec_cpu_down)
+		ppc_md.kexec_cpu_down(0, 0);
 
 	put_cpu();
 
@@ -239,8 +239,8 @@ static void kexec_prepare_cpus(void)
 	 * UP to an SMP kernel.
 	 */
 	smp_release_cpus();
-	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down(0);
+	if (ppc_md.kexec_cpu_down)
+		ppc_md.kexec_cpu_down(0, 0);
 	local_irq_disable();
 }
 
Index: kexec/include/asm-powerpc/machdep.h
===================================================================
--- kexec.orig/include/asm-powerpc/machdep.h
+++ kexec/include/asm-powerpc/machdep.h
@@ -91,7 +91,9 @@ struct machdep_calls {
 
 	void		(*init_IRQ)(void);
 	int		(*get_irq)(struct pt_regs *);
-	void		(*cpu_irq_down)(int secondary);
+#ifdef CONFIG_KEXEC
+	void		(*kexec_cpu_down)(int crash_shutdown, int secondary);
+#endif
 
 	/* PCI stuff */
 	/* Called after scanning the bus, before allocating resources */



More information about the Linuxppc64-dev mailing list