x86: merge smp_store_cpu_info
[sfrench/cifs-2.6.git] / arch / x86 / kernel / smpboot_64.c
index 329f9c53a335b4867c33f736a6c593b41b301ec7..c213345ca2f592d3957cbb94defe5cb8ddeb9cfa 100644 (file)
 /* Set when the idlers are all forked */
 int smp_threads_ready;
 
-/*
- * Trampoline 80x86 program as an array.
- */
-
-extern const unsigned char trampoline_data[];
-extern const unsigned char trampoline_end[];
-
 /* State of each CPU */
 DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
@@ -92,33 +85,11 @@ struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
 #define set_idle_for_cpu(x,p)   (idle_thread_array[(x)] = (p))
 #endif
 
-
-/*
- * Currently trivial. Write the real->protected mode
- * bootstrap into the page concerned. The caller
- * has made sure it's suitably aligned.
- */
-
-static unsigned long __cpuinit setup_trampoline(void)
+static inline void wait_for_init_deassert(atomic_t *deassert)
 {
-       void *tramp = __va(SMP_TRAMPOLINE_BASE); 
-       memcpy(tramp, trampoline_data, trampoline_end - trampoline_data);
-       return virt_to_phys(tramp);
-}
-
-/*
- * The bootstrap kernel entry code has set these up. Save them for
- * a given CPU
- */
-
-static void __cpuinit smp_store_cpu_info(int id)
-{
-       struct cpuinfo_x86 *c = &cpu_data(id);
-
-       *c = boot_cpu_data;
-       c->cpu_index = id;
-       identify_cpu(c);
-       print_cpu_info(c);
+       while (!atomic_read(deassert))
+               cpu_relax();
+       return;
 }
 
 static atomic_t init_deasserted __cpuinitdata;
@@ -138,8 +109,7 @@ void __cpuinit smp_callin(void)
         * our local APIC.  We have to wait for the IPI or we'll
         * lock up on an APIC access.
         */
-       while (!atomic_read(&init_deasserted))
-               cpu_relax();
+       wait_for_init_deassert(&init_deasserted);
 
        /*
         * (This works even if the APIC is not enabled.)
@@ -211,20 +181,6 @@ void __cpuinit smp_callin(void)
        cpu_set(cpuid, cpu_callin_map);
 }
 
-/* maps the cpu to the sched domain representing multi-core */
-cpumask_t cpu_coregroup_map(int cpu)
-{
-       struct cpuinfo_x86 *c = &cpu_data(cpu);
-       /*
-        * For perf, we return last level cache shared map.
-        * And for power savings, we return cpu_core_map
-        */
-       if (sched_mc_power_savings || sched_smt_power_savings)
-               return per_cpu(cpu_core_map, cpu);
-       else
-               return c->llc_shared_map;
-}
-
 /*
  * Setup code on secondary processor (after comming out of the trampoline)
  */
@@ -275,9 +231,9 @@ void __cpuinit start_secondary(void)
        /*
         * Allow the master to continue.
         */
+       spin_unlock(&vector_lock);
        cpu_set(smp_processor_id(), cpu_online_map);
        per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
-       spin_unlock(&vector_lock);
 
        unlock_ipi_call_lock();
 
@@ -310,8 +266,8 @@ static void inquire_remote_apic(int apicid)
                        printk(KERN_CONT
                               "a previous APIC delivery may have failed\n");
 
-               apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
-               apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]);
+               apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+               apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]);
 
                timeout = 0;
                do {
@@ -344,12 +300,12 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
        /*
         * Turn INIT on target chip
         */
-       apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+       apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
        /*
         * Send IPI
         */
-       apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
+       apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
                                | APIC_DM_INIT);
 
        Dprintk("Waiting for send to finish...\n");
@@ -360,10 +316,10 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
        Dprintk("Deasserting INIT.\n");
 
        /* Target chip */
-       apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+       apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
        /* Send IPI */
-       apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
+       apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
 
        Dprintk("Waiting for send to finish...\n");
        send_status = safe_apic_wait_icr_idle();
@@ -373,6 +329,14 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
 
        num_starts = 2;
 
+       /*
+        * Paravirt / VMI wants a startup IPI hook here to set up the
+        * target processor state.
+        */
+       startup_ipi_hook(phys_apicid, (unsigned long) start_secondary,
+                       (unsigned long) init_rsp);
+
+
        /*
         * Run STARTUP IPI loop.
         */
@@ -382,6 +346,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
 
        for (j = 1; j <= num_starts; j++) {
                Dprintk("Sending STARTUP #%d.\n",j);
+               apic_read_around(APIC_SPIV);
                apic_write(APIC_ESR, 0);
                apic_read(APIC_ESR);
                Dprintk("After apic_write.\n");
@@ -391,11 +356,11 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
                 */
 
                /* Target chip */
-               apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+               apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
                /* Boot on the stack */
                /* Kick the second */
-               apic_write(APIC_ICR, APIC_DM_STARTUP | (start_rip >> 12));
+               apic_write_around(APIC_ICR, APIC_DM_STARTUP | (start_rip>>12));
 
                /*
                 * Give the other CPU some time to accept the IPI.
@@ -415,6 +380,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
                 * Due to the Pentium erratum 3AP.
                 */
                if (maxlvt > 3) {
+                       apic_read_around(APIC_SPIV);
                        apic_write(APIC_ESR, 0);
                }
                accept_status = (apic_read(APIC_ESR) & 0xEF);
@@ -587,6 +553,8 @@ do_rest:
                if (cpu_isset(cpu, cpu_callin_map)) {
                        /* number CPUs logically, starting from 1 (BSP is 0) */
                        Dprintk("CPU has booted.\n");
+                       printk(KERN_INFO "CPU%d: ", cpu);
+                       print_cpu_info(&cpu_data(cpu));
                } else {
                        boot_error = 1;
                        if (*((volatile unsigned char *)phys_to_virt(SMP_TRAMPOLINE_BASE))
@@ -770,6 +738,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
         */
 
        setup_boot_clock();
+       printk(KERN_INFO "CPU%d: ", 0);
+       print_cpu_info(&cpu_data(0));
 }
 
 /*
@@ -850,86 +820,3 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
        setup_ioapic_dest();
        check_nmi_watchdog();
 }
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void __ref remove_cpu_from_maps(void)
-{
-       int cpu = smp_processor_id();
-
-       cpu_clear(cpu, cpu_callout_map);
-       cpu_clear(cpu, cpu_callin_map);
-       clear_bit(cpu, (unsigned long *)&cpu_initialized); /* was set by cpu_init() */
-       clear_node_cpumask(cpu);
-}
-
-int __cpu_disable(void)
-{
-       int cpu = smp_processor_id();
-
-       /*
-        * Perhaps use cpufreq to drop frequency, but that could go
-        * into generic code.
-        *
-        * We won't take down the boot processor on i386 due to some
-        * interrupts only being able to be serviced by the BSP.
-        * Especially so if we're not using an IOAPIC   -zwane
-        */
-       if (cpu == 0)
-               return -EBUSY;
-
-       if (nmi_watchdog == NMI_LOCAL_APIC)
-               stop_apic_nmi_watchdog(NULL);
-       clear_local_APIC();
-
-       /*
-        * HACK:
-        * Allow any queued timer interrupts to get serviced
-        * This is only a temporary solution until we cleanup
-        * fixup_irqs as we do for IA64.
-        */
-       local_irq_enable();
-       mdelay(1);
-
-       local_irq_disable();
-       remove_siblinginfo(cpu);
-
-       spin_lock(&vector_lock);
-       /* It's now safe to remove this processor from the online map */
-       cpu_clear(cpu, cpu_online_map);
-       spin_unlock(&vector_lock);
-       remove_cpu_from_maps();
-       fixup_irqs(cpu_online_map);
-       return 0;
-}
-
-void __cpu_die(unsigned int cpu)
-{
-       /* We don't do anything here: idle task is faking death itself. */
-       unsigned int i;
-
-       for (i = 0; i < 10; i++) {
-               /* They ack this in play_dead by setting CPU_DEAD */
-               if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
-                       printk ("CPU %d is now offline\n", cpu);
-                       if (1 == num_online_cpus())
-                               alternatives_smp_switch(0);
-                       return;
-               }
-               msleep(100);
-       }
-       printk(KERN_ERR "CPU %u didn't die...\n", cpu);
-}
-
-#else /* ... !CONFIG_HOTPLUG_CPU */
-
-int __cpu_disable(void)
-{
-       return -ENOSYS;
-}
-
-void __cpu_die(unsigned int cpu)
-{
-       /* We said "no" in __cpu_disable */
-       BUG();
-}
-#endif /* CONFIG_HOTPLUG_CPU */