struct smp_ops_t {
        void  (*message_pass)(int target, int msg);
        int   (*probe)(void);
-       void  (*kick_cpu)(int nr);
+       int   (*kick_cpu)(int nr);
        void  (*setup_cpu)(int nr);
        void  (*bringup_done)(void);
        void  (*take_timebase)(void);
 
 
 extern int smp_mpic_probe(void);
 extern void smp_mpic_setup_cpu(int cpu);
-extern void smp_generic_kick_cpu(int nr);
+extern int smp_generic_kick_cpu(int nr);
 
 extern void smp_generic_give_timebase(void);
 extern void smp_generic_take_timebase(void);
 
 static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
 
 #ifdef CONFIG_PPC64
-void __devinit smp_generic_kick_cpu(int nr)
+int __devinit smp_generic_kick_cpu(int nr)
 {
        BUG_ON(nr < 0 || nr >= NR_CPUS);
 
         */
        paca[nr].cpu_start = 1;
        smp_mb();
+
+       return 0;
 }
 #endif
 
 
        /* wake up cpus */
        DBG("smp: kicking cpu %d\n", cpu);
-       smp_ops->kick_cpu(cpu);
+       rc = smp_ops->kick_cpu(cpu);
+       if (rc) {
+               pr_err("smp: failed starting cpu %d (rc %d)\n", cpu, rc);
+               return rc;
+       }
 
        /*
         * wait to see if the cpu made a callin (is actually up).
 
        mpic_setup_this_cpu();
 }
 
-static void __cpuinit smp_iss4xx_kick_cpu(int cpu)
+static int __cpuinit smp_iss4xx_kick_cpu(int cpu)
 {
        struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
        const u64 *spin_table_addr_prop;
                                               NULL);
        if (spin_table_addr_prop == NULL) {
                pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", cpu);
-               return;
+               return -ENOENT;
        }
 
        /* Assume it's mapped as part of the linear mapping. This is a bit
        smp_wmb();
        spin_table[1] = __pa(start_secondary_47x);
        mb();
+
+       return 0;
 }
 
 static struct smp_ops_t iss_smp_ops = {
 
 #define NUM_BOOT_ENTRY         8
 #define SIZE_BOOT_ENTRY                (NUM_BOOT_ENTRY * sizeof(u32))
 
-static void __init
+static int __init
 smp_85xx_kick_cpu(int nr)
 {
        unsigned long flags;
 
        if (cpu_rel_addr == NULL) {
                printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
-               return;
+               return -ENOENT;
        }
 
        /*
                iounmap(bptr_vaddr);
 
        pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
+
+       return 0;
 }
 
 static void __init
 
 }
 
 
-static void __init
+static int __init
 smp_86xx_kick_cpu(int nr)
 {
        unsigned int save_vector;
        unsigned int *vector = (unsigned int *)(KERNELBASE + 0x100);
 
        if (nr < 0 || nr >= NR_CPUS)
-               return;
+               return -ENOENT;
 
        pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr);
 
        local_irq_restore(flags);
 
        pr_debug("wait CPU #%d for %d msecs.\n", nr, n);
+
+       return 0;
 }
 
 
 
        beatic_setup_cpu(cpu);
 }
 
-static void __devinit smp_celleb_kick_cpu(int nr)
+static int __devinit smp_celleb_kick_cpu(int nr)
 {
        BUG_ON(nr < 0 || nr >= NR_CPUS);
 
-       if (!smp_startup_cpu(nr))
-               return;
+       return smp_startup_cpu(nr);
 }
 
 static int smp_celleb_cpu_bootable(unsigned int nr)
 
        mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
 }
 
-static void __devinit smp_cell_kick_cpu(int nr)
+static int __devinit smp_cell_kick_cpu(int nr)
 {
        BUG_ON(nr < 0 || nr >= NR_CPUS);
 
        if (!smp_startup_cpu(nr))
-               return;
+               return -ENOENT;
 
        /*
         * The processor is currently spinning, waiting for the
         * the processor will continue on to secondary_start
         */
        paca[nr].cpu_start = 1;
+
+       return 0;
 }
 
 static int smp_cell_cpu_bootable(unsigned int nr)
 
 #include <asm/mpic.h>
 #include <asm/rtas.h>
 
-static void __devinit smp_chrp_kick_cpu(int nr)
+static int __devinit smp_chrp_kick_cpu(int nr)
 {
        *(unsigned long *)KERNELBASE = nr;
        asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
+
+       return 0;
 }
 
 static void __devinit smp_chrp_setup_cpu(int cpu_nr)
 
        return cpumask_weight(cpu_possible_mask);
 }
 
-static void smp_iSeries_kick_cpu(int nr)
+static int smp_iSeries_kick_cpu(int nr)
 {
        BUG_ON((nr < 0) || (nr >= NR_CPUS));
 
        /* Verify that our partition has a processor nr */
        if (lppaca_of(nr).dyn_proc_status >= 2)
-               return;
+               return -ENOENT;
 
        /* The processor is currently spinning, waiting
         * for the cpu_start field to become non-zero
         * continue on to secondary_start in iSeries_head.S
         */
        paca[nr].cpu_start = 1;
+
+       return 0;
 }
 
 static void __devinit smp_iSeries_setup_cpu(int nr)
 
        return ncpus;
 }
 
-static void __init smp_psurge_kick_cpu(int nr)
+static int __init smp_psurge_kick_cpu(int nr)
 {
        unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
        unsigned long a, flags;
                psurge_set_ipi(1);
 
        if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
+
+       return 0;
 }
 
 static struct irqaction psurge_irqaction = {
        return ncpus;
 }
 
-static void __devinit smp_core99_kick_cpu(int nr)
+static int __devinit smp_core99_kick_cpu(int nr)
 {
        unsigned int save_vector;
        unsigned long target, flags;
        unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
 
        if (nr < 0 || nr > 3)
-               return;
+               return -ENOENT;
 
        if (ppc_md.progress)
                ppc_md.progress("smp_core99_kick_cpu", 0x346);
 
        local_irq_restore(flags);
        if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
+
+       return 0;
 }
 
 static void __devinit smp_core99_setup_cpu(int cpu_nr)
 
 #endif
 }
 
-static void __devinit smp_pSeries_kick_cpu(int nr)
+static int __devinit smp_pSeries_kick_cpu(int nr)
 {
        BUG_ON(nr < 0 || nr >= NR_CPUS);
 
        if (!smp_startup_cpu(nr))
-               return;
+               return -ENOENT;
 
        /*
         * The processor is currently spinning, waiting for the
                                                "Ret= %ld\n", nr, rc);
        }
 #endif
+
+       return 0;
 }
 
 static int smp_pSeries_cpu_bootable(unsigned int nr)