/* Bring up a remote CPU */ int __cpu_up(unsigned int cpu) { int rc; printk("Bringing up CPU%d\n", cpu); rc = init_secondary_pagetables(cpu); if ( rc < 0 ) return rc; console_start_sync(); /* Secondary may use early_printk */ /* Tell the remote CPU which stack to boot on. */ init_data.stack = idle_vcpu[cpu]->arch.stack; /* Tell the remote CPU what is it's logical CPU ID */ init_data.cpuid = cpu; /* Open the gate for this CPU */ smp_up_cpu = cpu_logical_map(cpu); flush_xen_dcache(smp_up_cpu); rc = arch_cpu_up(cpu); console_end_sync(); if ( rc < 0 ) { printk("Failed to bring up CPU%d\n", cpu); return rc; } while ( !cpu_online(cpu) ) { cpu_relax(); process_pending_softirqs(); } return 0; }
/* Bring up a remote CPU */ int __cpu_up(unsigned int cpu) { int rc; s_time_t deadline; printk("Bringing up CPU%d\n", cpu); rc = init_secondary_pagetables(cpu); if ( rc < 0 ) return rc; console_start_sync(); /* Secondary may use early_printk */ /* Tell the remote CPU which stack to boot on. */ init_data.stack = idle_vcpu[cpu]->arch.stack; /* Tell the remote CPU what its logical CPU ID is. */ init_data.cpuid = cpu; /* Open the gate for this CPU */ smp_up_cpu = cpu_logical_map(cpu); clean_dcache(smp_up_cpu); rc = arch_cpu_up(cpu); console_end_sync(); if ( rc < 0 ) { printk("Failed to bring up CPU%d\n", cpu); return rc; } deadline = NOW() + MILLISECS(1000); while ( !cpu_online(cpu) && NOW() < deadline ) { cpu_relax(); process_pending_softirqs(); } /* * Nuke start of day info before checking one last time if the CPU * actually came online. If it is not online it may still be * trying to come up and may show up later unexpectedly. * * This doesn't completely avoid the possibility of the supposedly * failed CPU trying to progress with another CPUs stack settings * etc, but better than nothing, hopefully. */ init_data.stack = NULL; init_data.cpuid = ~0; smp_up_cpu = MPIDR_INVALID; clean_dcache(smp_up_cpu); if ( !cpu_online(cpu) ) { printk("CPU%d never came online\n", cpu); return -EIO; } return 0; }