From ed7f3ab5817cff246e973bd0f784d5d9f2f77e06 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Sat, 12 Nov 2005 00:06:05 +1100 Subject: [PATCH] --- yaml --- r: 14160 b: refs/heads/master c: c5e24354efae9f962e0e369d875d45f47e0bb9aa h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/powerpc/platforms/pseries/setup.c | 26 ++++++++++++++++++-- trunk/arch/ppc64/kernel/machine_kexec.c | 12 ++++----- trunk/include/asm-powerpc/machdep.h | 4 ++- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index 761a43800edf..a806c8c0d7e9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5cd16ee934eafca74a6bb790328950cec68a8b78 +refs/heads/master: c5e24354efae9f962e0e369d875d45f47e0bb9aa diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 31990829310c..b9d9732b2e06 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -200,14 +200,12 @@ static void __init pSeries_setup_arch(void) 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 @@ -595,6 +593,27 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus) 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, @@ -617,4 +636,7 @@ struct machdep_calls __initdata pSeries_md = { .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 }; diff --git a/trunk/arch/ppc64/kernel/machine_kexec.c b/trunk/arch/ppc64/kernel/machine_kexec.c index 07ea03598c00..203f1d5e6f10 100644 --- a/trunk/arch/ppc64/kernel/machine_kexec.c +++ b/trunk/arch/ppc64/kernel/machine_kexec.c @@ -185,8 +185,8 @@ void kexec_copy_flush(struct kimage *image) */ 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(); @@ -233,8 +233,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(); @@ -255,8 +255,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(); } diff --git a/trunk/include/asm-powerpc/machdep.h b/trunk/include/asm-powerpc/machdep.h index 5670f0cd6143..c011abb8b600 100644 --- a/trunk/include/asm-powerpc/machdep.h +++ b/trunk/include/asm-powerpc/machdep.h @@ -93,7 +93,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 */