[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: Reindent smpboot.c and clean up a little.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1274111904 -3600
# Node ID 89a2f9ad02f23c24a06274a1217991181f19930b
# Parent  c7dde06ba1c35176e69e65dc3c7e6067e713bc47
x86: Reindent smpboot.c and clean up a little.

No semantic changes.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/cpu/common.c                       |    7 
 xen/arch/x86/smpboot.c                          | 1709 +++++++++++-------------
 xen/include/asm-x86/mach-default/mach_wakecpu.h |    8 
 xen/include/asm-x86/smp.h                       |    2 
 4 files changed, 837 insertions(+), 889 deletions(-)

diff -r c7dde06ba1c3 -r 89a2f9ad02f2 xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c Mon May 17 16:28:56 2010 +0100
+++ b/xen/arch/x86/cpu/common.c Mon May 17 16:58:24 2010 +0100
@@ -550,7 +550,7 @@ void __cpuinit print_cpu_info(unsigned i
                printk("\n");
 }
 
-cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
+static cpumask_t cpu_initialized;
 
 /* This is hacky. :)
  * We're emulating future behavior.
@@ -629,8 +629,7 @@ void __cpuinit cpu_init(void)
 #undef CD
 }
 
-void __cpuinit cpu_uninit(void)
-{
-       int cpu = raw_smp_processor_id();
+void cpu_uninit(unsigned int cpu)
+{
        cpu_clear(cpu, cpu_initialized);
 }
diff -r c7dde06ba1c3 -r 89a2f9ad02f2 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Mon May 17 16:28:56 2010 +0100
+++ b/xen/arch/x86/smpboot.c    Mon May 17 16:58:24 2010 +0100
@@ -1,37 +1,24 @@
 /*
- *     x86 SMP booting functions
+ * x86 SMP booting functions
  *
- *     (c) 1995 Alan Cox, Building #3 <alan@xxxxxxxxxx>
- *     (c) 1998, 1999, 2000 Ingo Molnar <mingo@xxxxxxxxxx>
- *
- *     Much of the core SMP work is based on previous work by Thomas Radke, to
- *     whom a great many thanks are extended.
- *
- *     Thanks to Intel for making available several different Pentium,
- *     Pentium Pro and Pentium-II/Xeon MP machines.
- *     Original development of Linux SMP code supported by Caldera.
- *
- *     This code is released under the GNU General Public License version 2 or
- *     later.
- *
- *     Fixes
- *             Felix Koop      :       NR_CPUS used properly
- *             Jose Renau      :       Handle single CPU case.
- *             Alan Cox        :       By repeated request 8) - Total BogoMIPS 
report.
- *             Greg Wright     :       Fix for kernel stacks panic.
- *             Erich Boleyn    :       MP v1.4 and additional changes.
- *     Matthias Sattler        :       Changes for 2.1 kernel map.
- *     Michel Lespinasse       :       Changes for 2.1 kernel map.
- *     Michael Chastain        :       Change trampoline.S to gnu as.
- *             Alan Cox        :       Dumb bug: 'B' step PPro's are fine
- *             Ingo Molnar     :       Added APIC timers, based on code
- *                                     from Jose Renau
- *             Ingo Molnar     :       various cleanups and rewrites
- *             Tigran Aivazian :       fixed "0.00 in /proc/uptime on SMP" bug.
- *     Maciej W. Rozycki       :       Bits for genuine 82489DX APICs
- *             Martin J. Bligh :       Added support for multi-quad systems
- *             Dave Jones      :       Report invalid combinations of Athlon 
CPUs.
-*              Rusty Russell   :       Hacked into shape for new "hotplug" 
boot process. */
+ * This inherits a great deal from Linux's SMP boot code:
+ *  (c) 1995 Alan Cox, Building #3 <alan@xxxxxxxxxx>
+ *  (c) 1998, 1999, 2000 Ingo Molnar <mingo@xxxxxxxxxx>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 
 #include <xen/config.h>
 #include <xen/init.h>
@@ -85,8 +72,7 @@ static cpumask_t smp_commenced_mask;
 
 struct cpuinfo_x86 cpu_data[NR_CPUS];
 
-u32 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
-                       { [0 ... NR_CPUS-1] = -1U };
+u32 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = -1U };
 
 static void map_cpu_to_logical_apicid(void);
 
@@ -96,947 +82,918 @@ void *stack_base[NR_CPUS];
 
 static void smp_store_cpu_info(int id)
 {
-       struct cpuinfo_x86 *c = cpu_data + id;
-
-       *c = boot_cpu_data;
-       if (id!=0)
-               identify_cpu(c);
-       /*
-        * Mask B, Pentium, but not Pentium MMX
-        */
-       if (c->x86_vendor == X86_VENDOR_INTEL &&
-           c->x86 == 5 &&
-           c->x86_mask >= 1 && c->x86_mask <= 4 &&
-           c->x86_model <= 3)
-               /*
-                * Remember we have B step Pentia with bugs
-                */
-               smp_b_stepping = 1;
-
-       /*
-        * Certain Athlons might work (for various values of 'work') in SMP
-        * but they are not certified as MP capable.
-        */
-       if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
-
-               /* Athlon 660/661 is valid. */  
-               if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1)))
-                       goto valid_k7;
-
-               /* Duron 670 is valid */
-               if ((c->x86_model==7) && (c->x86_mask==0))
-                       goto valid_k7;
-
-               /*
-                * Athlon 662, Duron 671, and Athlon >model 7 have capability 
bit.
-                * It's worth noting that the A5 stepping (662) of some Athlon 
XP's
-                * have the MP bit set.
-                * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for 
more.
-                */
-               if (((c->x86_model==6) && (c->x86_mask>=2)) ||
-                   ((c->x86_model==7) && (c->x86_mask>=1)) ||
-                    (c->x86_model> 7))
-                       if (cpu_has_mp)
-                               goto valid_k7;
-
-               /* If we get here, it's not a certified SMP capable AMD system. 
*/
-               add_taint(TAINT_UNSAFE_SMP);
-       }
-
-valid_k7:
-       ;
+    struct cpuinfo_x86 *c = cpu_data + id;
+
+    *c = boot_cpu_data;
+    if ( id != 0 )
+        identify_cpu(c);
+
+    /* Mask B, Pentium, but not Pentium MMX -- remember it, as it has bugs. */
+    if ( (c->x86_vendor == X86_VENDOR_INTEL) &&
+         (c->x86 == 5) &&
+         ((c->x86_mask >= 1) && (c->x86_mask <= 4)) &&
+         (c->x86_model <= 3) )
+        smp_b_stepping = 1;
+
+    /*
+     * Certain Athlons might work (for various values of 'work') in SMP
+     * but they are not certified as MP capable.
+     */
+    if ( (c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6) )
+    {
+        /* Athlon 660/661 is valid. */ 
+        if ( (c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1)) )
+            goto valid_k7;
+
+        /* Duron 670 is valid */
+        if ( (c->x86_model==7) && (c->x86_mask==0) )
+            goto valid_k7;
+
+        /*
+         * Athlon 662, Duron 671, and Athlon >model 7 have capability bit.
+         * It's worth noting that the A5 stepping (662) of some Athlon XP's
+         * have the MP bit set.
+         * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for more.
+         */
+        if ( ((c->x86_model==6) && (c->x86_mask>=2)) ||
+             ((c->x86_model==7) && (c->x86_mask>=1)) ||
+             (c->x86_model> 7) )
+            if (cpu_has_mp)
+                goto valid_k7;
+
+        /* If we get here, it's not a certified SMP capable AMD system. */
+        add_taint(TAINT_UNSAFE_SMP);
+    }
+
+ valid_k7:
+    ;
 }
 
 static atomic_t init_deasserted;
 
 void smp_callin(void)
 {
-       int cpuid, phys_id, i;
-
-       /*
-        * If waken up by an INIT in an 82489DX configuration
-        * we may get here before an INIT-deassert IPI reaches
-        * our local APIC.  We have to wait for the IPI or we'll
-        * lock up on an APIC access.
-        */
-       wait_for_init_deassert(&init_deasserted);
-
-       if ( x2apic_enabled )
-               enable_x2apic();
-
-       /*
-        * (This works even if the APIC is not enabled.)
-        */
-       phys_id = get_apic_id();
-       cpuid = smp_processor_id();
-       if (cpu_isset(cpuid, cpu_callin_map)) {
-               printk("huh, phys CPU#%d, CPU#%d already present??\n",
-                                       phys_id, cpuid);
-               BUG();
-       }
-       Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);
-
-       /*
-        * STARTUP IPIs are fragile beasts as they might sometimes
-        * trigger some glue motherboard logic. Complete APIC bus
-        * silence for 1 second, this overestimates the time the
-        * boot CPU is spending to send the up to 2 STARTUP IPIs
-        * by a factor of two. This should be enough.
-        */
-
-       /*
-        * Waiting 2s total for startup
-        */
-       for (i = 0; i < 200; i++) {
-               /*
-                * Has the boot CPU finished it's STARTUP sequence?
-                */
-               if (cpu_isset(cpuid, cpu_callout_map))
-                       break;
-               cpu_relax();
-               mdelay(10);
-       }
-
-       if (!cpu_isset(cpuid, cpu_callout_map)) {
-               printk("BUG: CPU%d started up but did not get a callout!\n",
-                       cpuid);
-               BUG();
-       }
-
-       /*
-        * the boot CPU has finished the init stage and is spinning
-        * on callin_map until we finish. We are free to set up this
-        * CPU, first the APIC. (this is probably redundant on most
-        * boards)
-        */
-
-       Dprintk("CALLIN, before setup_local_APIC().\n");
-       smp_callin_clear_local_apic();
-       setup_local_APIC();
-       map_cpu_to_logical_apicid();
-
-       /*
-        * Save our processor parameters
-        */
-       smp_store_cpu_info(cpuid);
-
-       /*
-        * Allow the master to continue.
-        */
-       cpu_set(cpuid, cpu_callin_map);
+    int cpuid, phys_id, i;
+
+    /*
+     * If waken up by an INIT in an 82489DX configuration
+     * we may get here before an INIT-deassert IPI reaches
+     * our local APIC.  We have to wait for the IPI or we'll
+     * lock up on an APIC access.
+     */
+    wait_for_init_deassert(&init_deasserted);
+
+    if ( x2apic_enabled )
+        enable_x2apic();
+
+    /*
+     * (This works even if the APIC is not enabled.)
+     */
+    phys_id = get_apic_id();
+    cpuid = smp_processor_id();
+    if ( cpu_isset(cpuid, cpu_callin_map) )
+    {
+        printk("huh, phys CPU#%d, CPU#%d already present??\n",
+               phys_id, cpuid);
+        BUG();
+    }
+    Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);
+
+    /*
+     * STARTUP IPIs are fragile beasts as they might sometimes
+     * trigger some glue motherboard logic. Complete APIC bus
+     * silence for 1 second, this overestimates the time the
+     * boot CPU is spending to send the up to 2 STARTUP IPIs
+     * by a factor of two. This should be enough.
+     */
+
+    /* Wait 2s total for startup. */
+    for ( i = 0; (i < 200) && !cpu_isset(cpuid, cpu_callout_map); i++ )
+    {
+        cpu_relax();
+        mdelay(10);
+    }
+
+    if ( !cpu_isset(cpuid, cpu_callout_map) )
+    {
+        printk("BUG: CPU%d started up but did not get a callout!\n",
+               cpuid);
+        BUG();
+    }
+
+    /*
+     * the boot CPU has finished the init stage and is spinning
+     * on callin_map until we finish. We are free to set up this
+     * CPU, first the APIC. (this is probably redundant on most
+     * boards)
+     */
+
+    Dprintk("CALLIN, before setup_local_APIC().\n");
+    smp_callin_clear_local_apic();
+    setup_local_APIC();
+    map_cpu_to_logical_apicid();
+
+    /* Save our processor parameters. */
+    smp_store_cpu_info(cpuid);
+
+    /* Allow the master to continue. */
+    cpu_set(cpuid, cpu_callin_map);
 }
 
 static int booting_cpu;
 
-/* representing cpus for which sibling maps can be computed */
+/* CPUs for which sibling maps can be computed. */
 static cpumask_t cpu_sibling_setup_map;
 
-static inline void
-set_cpu_sibling_map(int cpu)
-{
-       int i;
-       struct cpuinfo_x86 *c = cpu_data;
-
-       cpu_set(cpu, cpu_sibling_setup_map);
-
-       if (c[cpu].x86_num_siblings > 1) {
-               for_each_cpu_mask(i, cpu_sibling_setup_map) {
-                       if (phys_proc_id[cpu] == phys_proc_id[i] &&
-                           cpu_core_id[cpu] == cpu_core_id[i]) {
-                               cpu_set(i, per_cpu(cpu_sibling_map, cpu));
-                               cpu_set(cpu, per_cpu(cpu_sibling_map, i));
-                               cpu_set(i, per_cpu(cpu_core_map, cpu));
-                               cpu_set(cpu, per_cpu(cpu_core_map, i));
-                       }
-               }
-       } else {
-               cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
-       }
-
-       if (c[cpu].x86_max_cores == 1) {
-               per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
-               c[cpu].booted_cores = 1;
-               return;
-       }
-
-       for_each_cpu_mask(i, cpu_sibling_setup_map) {
-               if (phys_proc_id[cpu] == phys_proc_id[i]) {
-                       cpu_set(i, per_cpu(cpu_core_map, cpu));
-                       cpu_set(cpu, per_cpu(cpu_core_map, i));
-                       /*
-                        *  Does this new cpu bringup a new core?
-                        */
-                       if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) {
-                               /*
-                                * for each core in package, increment
-                                * the booted_cores for this new cpu
-                                */
-                               if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
-                                       c[cpu].booted_cores++;
-                               /*
-                                * increment the core count for all
-                                * the other cpus in this package
-                                */
-                               if (i != cpu)
-                                       c[i].booted_cores++;
-                       } else if (i != cpu && !c[cpu].booted_cores)
-                               c[cpu].booted_cores = c[i].booted_cores;
-               }
-       }
+static void set_cpu_sibling_map(int cpu)
+{
+    int i;
+    struct cpuinfo_x86 *c = cpu_data;
+
+    cpu_set(cpu, cpu_sibling_setup_map);
+
+    if ( c[cpu].x86_num_siblings > 1 )
+    {
+        for_each_cpu_mask ( i, cpu_sibling_setup_map )
+        {
+            if ( (phys_proc_id[cpu] == phys_proc_id[i]) &&
+                 (cpu_core_id[cpu] == cpu_core_id[i]) )
+            {
+                cpu_set(i, per_cpu(cpu_sibling_map, cpu));
+                cpu_set(cpu, per_cpu(cpu_sibling_map, i));
+                cpu_set(i, per_cpu(cpu_core_map, cpu));
+                cpu_set(cpu, per_cpu(cpu_core_map, i));
+            }
+        }
+    }
+    else
+    {
+        cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
+    }
+
+    if ( c[cpu].x86_max_cores == 1 )
+    {
+        per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
+        c[cpu].booted_cores = 1;
+        return;
+    }
+
+    for_each_cpu_mask ( i, cpu_sibling_setup_map )
+    {
+        if ( phys_proc_id[cpu] == phys_proc_id[i] )
+        {
+            cpu_set(i, per_cpu(cpu_core_map, cpu));
+            cpu_set(cpu, per_cpu(cpu_core_map, i));
+            /*
+             *  Does this new cpu bringup a new core?
+             */
+            if ( cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1 )
+            {
+                /*
+                 * for each core in package, increment
+                 * the booted_cores for this new cpu
+                 */
+                if ( first_cpu(per_cpu(cpu_sibling_map, i)) == i )
+                    c[cpu].booted_cores++;
+                /*
+                 * increment the core count for all
+                 * the other cpus in this package
+                 */
+                if ( i != cpu )
+                    c[i].booted_cores++;
+            }
+            else if ( (i != cpu) && !c[cpu].booted_cores )
+            {
+                c[cpu].booted_cores = c[i].booted_cores;
+            }
+        }
+    }
 }
 
 static void construct_percpu_idt(unsigned int cpu)
 {
-       unsigned char idt_load[10];
-
-       *(unsigned short *)(&idt_load[0]) = (IDT_ENTRIES*sizeof(idt_entry_t))-1;
-       *(unsigned long  *)(&idt_load[2]) = (unsigned long)idt_tables[cpu];
-       __asm__ __volatile__ ( "lidt %0" : "=m" (idt_load) );
-}
-
-/*
- * Activate a secondary processor.
- */
+    unsigned char idt_load[10];
+
+    *(unsigned short *)(&idt_load[0]) = (IDT_ENTRIES*sizeof(idt_entry_t))-1;
+    *(unsigned long  *)(&idt_load[2]) = (unsigned long)idt_tables[cpu];
+    __asm__ __volatile__ ( "lidt %0" : "=m" (idt_load) );
+}
+
 void start_secondary(void *unused)
 {
-       /*
-        * Dont put anything before smp_callin(), SMP
-        * booting is too fragile that we want to limit the
-        * things done here to the most necessary things.
-        */
-       unsigned int cpu = booting_cpu;
-
-       set_processor_id(cpu);
-       set_current(idle_vcpu[cpu]);
-       this_cpu(curr_vcpu) = idle_vcpu[cpu];
-       if ( cpu_has_efer )
-               rdmsrl(MSR_EFER, this_cpu(efer));
-       asm volatile ( "mov %%cr4,%0" : "=r" (this_cpu(cr4)) );
-
-       /*
-        * Just as during early bootstrap, it is convenient here to disable
-        * spinlock checking while we have IRQs disabled. This allows us to
-        * acquire IRQ-unsafe locks when it would otherwise be disallowed.
-        * 
-        * It is safe because the race we are usually trying to avoid involves
-        * a group of CPUs rendezvousing in an IPI handler, where one cannot
-        * join because it is spinning with IRQs disabled waiting to acquire a
-        * lock held by another in the rendezvous group (the lock must be an
-        * IRQ-unsafe lock since the CPU took the IPI after acquiring it, and
-        * hence had IRQs enabled). This is a deadlock scenario.
-        * 
-        * However, no CPU can be involved in rendezvous until it is online,
-        * hence no such group can be waiting for this CPU until it is
-        * visible in cpu_online_map. Hence such a deadlock is not possible.
-        */
-       spin_debug_disable();
-
-       percpu_traps_init();
-
-       cpu_init();
-
-       smp_callin();
-       while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
-               cpu_relax();
-
-       /*
-        * At this point, boot CPU has fully initialised the IDT. It is
-        * now safe to make ourselves a private copy.
-        */
-       construct_percpu_idt(cpu);
-
-       setup_secondary_APIC_clock();
-       enable_APIC_timer();
-       /*
-        * low-memory mappings have been cleared, flush them from
-        * the local TLBs too.
-        */
-       flush_tlb_local();
-
-       /* This must be done before setting cpu_online_map */
-       spin_debug_enable();
-       set_cpu_sibling_map(raw_smp_processor_id());
-       wmb();
-
-       /*
-        * We need to hold vector_lock so there the set of online cpus
-        * does not change while we are assigning vectors to cpus.  Holding
-        * this lock ensures we don't half assign or remove an irq from a cpu.
-        */
-       lock_vector_lock();
-       __setup_vector_irq(smp_processor_id());
-       cpu_set(smp_processor_id(), cpu_online_map);
-       unlock_vector_lock();
-
-       per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
-
-       init_percpu_time();
-
-       /* We can take interrupts now: we're officially "up". */
-       local_irq_enable();
-       mtrr_ap_init();
-
-       microcode_resume_cpu(cpu);
-
-       wmb();
-       startup_cpu_idle_loop();
+    /*
+     * Dont put anything before smp_callin(), SMP booting is so fragile that we
+     * want to limit the things done here to the most necessary things.
+     */
+    unsigned int cpu = booting_cpu;
+
+    set_processor_id(cpu);
+    set_current(idle_vcpu[cpu]);
+    this_cpu(curr_vcpu) = idle_vcpu[cpu];
+    if ( cpu_has_efer )
+        rdmsrl(MSR_EFER, this_cpu(efer));
+    asm volatile ( "mov %%cr4,%0" : "=r" (this_cpu(cr4)) );
+
+    /*
+     * Just as during early bootstrap, it is convenient here to disable
+     * spinlock checking while we have IRQs disabled. This allows us to
+     * acquire IRQ-unsafe locks when it would otherwise be disallowed.
+     * 
+     * It is safe because the race we are usually trying to avoid involves
+     * a group of CPUs rendezvousing in an IPI handler, where one cannot
+     * join because it is spinning with IRQs disabled waiting to acquire a
+     * lock held by another in the rendezvous group (the lock must be an
+     * IRQ-unsafe lock since the CPU took the IPI after acquiring it, and
+     * hence had IRQs enabled). This is a deadlock scenario.
+     * 
+     * However, no CPU can be involved in rendezvous until it is online,
+     * hence no such group can be waiting for this CPU until it is
+     * visible in cpu_online_map. Hence such a deadlock is not possible.
+     */
+    spin_debug_disable();
+
+    percpu_traps_init();
+
+    cpu_init();
+
+    smp_callin();
+    while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
+        cpu_relax();
+
+    /*
+     * At this point, boot CPU has fully initialised the IDT. It is
+     * now safe to make ourselves a private copy.
+     */
+    construct_percpu_idt(cpu);
+
+    setup_secondary_APIC_clock();
+    enable_APIC_timer();
+    /*
+     * low-memory mappings have been cleared, flush them from
+     * the local TLBs too.
+     */
+    flush_tlb_local();
+
+    /* This must be done before setting cpu_online_map */
+    spin_debug_enable();
+    set_cpu_sibling_map(raw_smp_processor_id());
+    wmb();
+
+    /*
+     * We need to hold vector_lock so there the set of online cpus
+     * does not change while we are assigning vectors to cpus.  Holding
+     * this lock ensures we don't half assign or remove an irq from a cpu.
+     */
+    lock_vector_lock();
+    __setup_vector_irq(smp_processor_id());
+    cpu_set(smp_processor_id(), cpu_online_map);
+    unlock_vector_lock();
+
+    per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+
+    init_percpu_time();
+
+    /* We can take interrupts now: we're officially "up". */
+    local_irq_enable();
+    mtrr_ap_init();
+
+    microcode_resume_cpu(cpu);
+
+    wmb();
+    startup_cpu_idle_loop();
 }
 
 extern struct {
-       void * esp;
-       unsigned short ss;
+    void * esp;
+    unsigned short ss;
 } stack_start;
 
-u32 cpu_2_logical_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 
BAD_APICID };
+u32 cpu_2_logical_apicid[NR_CPUS] __read_mostly =
+    { [0 ... NR_CPUS-1] = BAD_APICID };
 
 static void map_cpu_to_logical_apicid(void)
 {
-       int cpu = smp_processor_id();
-       int apicid = logical_smp_processor_id();
-
-       cpu_2_logical_apicid[cpu] = apicid;
+    int cpu = smp_processor_id();
+    int apicid = logical_smp_processor_id();
+
+    cpu_2_logical_apicid[cpu] = apicid;
 }
 
 static void unmap_cpu_to_logical_apicid(int cpu)
 {
-       cpu_2_logical_apicid[cpu] = BAD_APICID;
+    cpu_2_logical_apicid[cpu] = BAD_APICID;
 }
 
 #if APIC_DEBUG
-static inline void __inquire_remote_apic(int apicid)
-{
-       int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
-       char *names[] = { "ID", "VERSION", "SPIV" };
-       int timeout, status;
-
-       printk("Inquiring remote APIC #%d...\n", apicid);
-
-       for (i = 0; i < ARRAY_SIZE(regs); i++) {
-               printk("... APIC #%d %s: ", apicid, names[i]);
-
-               /*
-                * Wait for idle.
-                */
-               apic_wait_icr_idle();
-
-               apic_icr_write(APIC_DM_REMRD | regs[i], apicid);
-
-               timeout = 0;
-               do {
-                       udelay(100);
-                       status = apic_read(APIC_ICR) & APIC_ICR_RR_MASK;
-               } while (status == APIC_ICR_RR_INPROG && timeout++ < 1000);
-
-               switch (status) {
-               case APIC_ICR_RR_VALID:
-                       status = apic_read(APIC_RRR);
-                       printk("%08x\n", status);
-                       break;
-               default:
-                       printk("failed\n");
-               }
-       }
+static void __inquire_remote_apic(int apicid)
+{
+    int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
+    char *names[] = { "ID", "VERSION", "SPIV" };
+    int timeout, status;
+
+    printk("Inquiring remote APIC #%d...\n", apicid);
+
+    for ( i = 0; i < ARRAY_SIZE(regs); i++ )
+    {
+        printk("... APIC #%d %s: ", apicid, names[i]);
+
+        /*
+         * Wait for idle.
+         */
+        apic_wait_icr_idle();
+
+        apic_icr_write(APIC_DM_REMRD | regs[i], apicid);
+
+        timeout = 0;
+        do {
+            udelay(100);
+            status = apic_read(APIC_ICR) & APIC_ICR_RR_MASK;
+        } while ( status == APIC_ICR_RR_INPROG && timeout++ < 1000 );
+
+        switch ( status )
+        {
+        case APIC_ICR_RR_VALID:
+            status = apic_read(APIC_RRR);
+            printk("%08x\n", status);
+            break;
+        default:
+            printk("failed\n");
+        }
+    }
 }
 #endif
 
 static int wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
 {
-       unsigned long send_status = 0, accept_status = 0;
-       int maxlvt, timeout, num_starts, j;
-
-       /*
-        * Be paranoid about clearing APIC errors.
-        */
-       if (APIC_INTEGRATED(apic_version[phys_apicid])) {
-               apic_read_around(APIC_SPIV);
-               apic_write(APIC_ESR, 0);
-               apic_read(APIC_ESR);
-       }
-
-       Dprintk("Asserting INIT.\n");
-
-       /*
-        * Turn INIT on target chip via IPI
-        */
-       apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
-                               phys_apicid);
-
-       Dprintk("Waiting for send to finish...\n");
-       timeout = 0;
-       do {
-               Dprintk("+");
-               udelay(100);
-               if ( !x2apic_enabled )
-                       send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
-               else
-                       send_status = 0; /* We go out of the loop dirctly. */
-       } while (send_status && (timeout++ < 1000));
-
-       mdelay(10);
-
-       Dprintk("Deasserting INIT.\n");
-
-       apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
-
-       Dprintk("Waiting for send to finish...\n");
-       timeout = 0;
-       do {
-               Dprintk("+");
-               udelay(100);
-               if ( !x2apic_enabled )
-                       send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
-               else
-                       send_status = 0; /* We go out of the loop dirctly. */
-       } while (send_status && (timeout++ < 1000));
-
-       atomic_set(&init_deasserted, 1);
-
-       /*
-        * Should we send STARTUP IPIs ?
-        *
-        * Determine this based on the APIC version.
-        * If we don't have an integrated APIC, don't send the STARTUP IPIs.
-        */
-       if (APIC_INTEGRATED(apic_version[phys_apicid]))
-               num_starts = 2;
-       else
-               num_starts = 0;
-
-       /*
-        * Run STARTUP IPI loop.
-        */
-       Dprintk("#startup loops: %d.\n", num_starts);
-
-       maxlvt = get_maxlvt();
-
-       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");
-
-               /*
-                * STARTUP IPI
-                * Boot on the stack
-                */
-               apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12), 
phys_apicid);
-
-               /*
-                * Give the other CPU some time to accept the IPI.
-                */
-               udelay(300);
-
-               Dprintk("Startup point 1.\n");
-
-               Dprintk("Waiting for send to finish...\n");
-               timeout = 0;
-               do {
-                       Dprintk("+");
-                       udelay(100);
-                       send_status = (x2apic_enabled ? 0 :
-                                      apic_read(APIC_ICR) & APIC_ICR_BUSY);
-               } while (send_status && (timeout++ < 1000));
-
-               /*
-                * Give the other CPU some time to accept the IPI.
-                */
-               udelay(200);
-               /*
-                * 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);
-               if (send_status || accept_status)
-                       break;
-       }
-       Dprintk("After Startup.\n");
-
-       if (send_status)
-               printk("APIC never delivered???\n");
-       if (accept_status)
-               printk("APIC delivery error (%lx).\n", accept_status);
-
-       return (send_status | accept_status);
-}
-
-extern cpumask_t cpu_initialized;
-/*
- * Caller should hold cpu_add_remove_lock if not called when booting
- */
+    unsigned long send_status = 0, accept_status = 0;
+    int maxlvt, timeout, num_starts, i;
+
+    /*
+     * Be paranoid about clearing APIC errors.
+     */
+    if ( APIC_INTEGRATED(apic_version[phys_apicid]) )
+    {
+        apic_read_around(APIC_SPIV);
+        apic_write(APIC_ESR, 0);
+        apic_read(APIC_ESR);
+    }
+
+    Dprintk("Asserting INIT.\n");
+
+    /*
+     * Turn INIT on target chip via IPI
+     */
+    apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
+                   phys_apicid);
+
+    Dprintk("Waiting for send to finish...\n");
+    timeout = 0;
+    do {
+        Dprintk("+");
+        udelay(100);
+        if ( !x2apic_enabled )
+            send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
+    } while ( send_status && (timeout++ < 1000) );
+
+    mdelay(10);
+
+    Dprintk("Deasserting INIT.\n");
+
+    apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
+
+    Dprintk("Waiting for send to finish...\n");
+    timeout = 0;
+    do {
+        Dprintk("+");
+        udelay(100);
+        if ( !x2apic_enabled )
+            send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
+    } while ( send_status && (timeout++ < 1000) );
+
+    atomic_set(&init_deasserted, 1);
+
+    /*
+     * Should we send STARTUP IPIs ?
+     *
+     * Determine this based on the APIC version.
+     * If we don't have an integrated APIC, don't send the STARTUP IPIs.
+     */
+    num_starts = APIC_INTEGRATED(apic_version[phys_apicid]) ? 2 : 0;
+
+    /* Run STARTUP IPI loop. */
+    Dprintk("#startup loops: %d.\n", num_starts);
+
+    maxlvt = get_maxlvt();
+
+    for ( i = 0; i < num_starts; i++ )
+    {
+        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");
+
+        /*
+         * STARTUP IPI
+         * Boot on the stack
+         */
+        apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12), phys_apicid);
+
+        /* Give the other CPU some time to accept the IPI. */
+        udelay(300);
+
+        Dprintk("Startup point 1.\n");
+
+        Dprintk("Waiting for send to finish...\n");
+        timeout = 0;
+        do {
+            Dprintk("+");
+            udelay(100);
+            if ( !x2apic_enabled )
+            send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
+        } while ( send_status && (timeout++ < 1000) );
+
+        /* Give the other CPU some time to accept the IPI. */
+        udelay(200);
+
+        /* 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);
+        if ( send_status || accept_status )
+            break;
+    }
+    Dprintk("After Startup.\n");
+
+    if ( send_status )
+        printk("APIC never delivered???\n");
+    if ( accept_status )
+        printk("APIC delivery error (%lx).\n", accept_status);
+
+    return (send_status | accept_status);
+}
+
 int alloc_cpu_id(void)
 {
-       cpumask_t       tmp_map;
-       int cpu;
-       cpus_complement(tmp_map, cpu_present_map);
-       cpu = first_cpu(tmp_map);
-       if (cpu >= NR_CPUS)
-               return -ENODEV;
-       return cpu;
+    cpumask_t tmp_map;
+    int cpu;
+    cpus_complement(tmp_map, cpu_present_map);
+    cpu = first_cpu(tmp_map);
+    return (cpu < NR_CPUS) ? cpu : -ENODEV;
 }
 
 static void *prepare_idle_stack(unsigned int cpu)
 {
-       if (!stack_base[cpu])
-               stack_base[cpu] = alloc_xenheap_pages(STACK_ORDER, 0);
-
-       return stack_base[cpu];
+    if ( !stack_base[cpu] )
+        stack_base[cpu] = alloc_xenheap_pages(STACK_ORDER, 0);
+    return stack_base[cpu];
 }
 
 static int do_boot_cpu(int apicid, int cpu)
-/*
- * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
- * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
- * Returns zero if CPU booted OK, else error code from wakeup_secondary_cpu.
- */
-{
-       unsigned long boot_error;
-       unsigned int order;
-       int timeout;
-       unsigned long start_eip;
-       unsigned short nmi_high = 0, nmi_low = 0;
-       struct vcpu *v;
-       struct desc_struct *gdt;
+{
+    unsigned long boot_error;
+    unsigned int order;
+    int timeout;
+    unsigned long start_eip;
+    struct vcpu *v;
+    struct desc_struct *gdt;
 #ifdef __x86_64__
-       struct page_info *page;
+    struct page_info *page;
 #endif
 
-       /*
-        * Save current MTRR state in case it was changed since early boot
-        * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
-        */
-       mtrr_save_state();
-
-       booting_cpu = cpu;
-
-       v = alloc_idle_vcpu(cpu);
-       BUG_ON(v == NULL);
-
-       /* start_eip had better be page-aligned! */
-       start_eip = setup_trampoline();
-
-       /* So we see what's up   */
-       if (opt_cpu_info)
-               printk("Booting processor %d/%d eip %lx\n",
-                      cpu, apicid, start_eip);
-
-       stack_start.esp = prepare_idle_stack(cpu);
-
-       /* Debug build: detect stack overflow by setting up a guard page. */
-       memguard_guard_stack(stack_start.esp);
-
-       gdt = per_cpu(gdt_table, cpu);
-       if (gdt == boot_cpu_gdt_table) {
-               order = get_order_from_pages(NR_RESERVED_GDT_PAGES);
+    /*
+     * Save current MTRR state in case it was changed since early boot
+     * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
+     */
+    mtrr_save_state();
+
+    booting_cpu = cpu;
+
+    v = alloc_idle_vcpu(cpu);
+    BUG_ON(v == NULL);
+
+    /* start_eip had better be page-aligned! */
+    start_eip = setup_trampoline();
+
+    /* So we see what's up   */
+    if (opt_cpu_info)
+        printk("Booting processor %d/%d eip %lx\n",
+               cpu, apicid, start_eip);
+
+    stack_start.esp = prepare_idle_stack(cpu);
+
+    /* Debug build: detect stack overflow by setting up a guard page. */
+    memguard_guard_stack(stack_start.esp);
+
+    gdt = per_cpu(gdt_table, cpu);
+    if ( gdt == boot_cpu_gdt_table )
+    {
+        order = get_order_from_pages(NR_RESERVED_GDT_PAGES);
 #ifdef __x86_64__
-               page = alloc_domheap_pages(NULL, order,
-                                          MEMF_node(cpu_to_node(cpu)));
-               per_cpu(compat_gdt_table, cpu) = gdt = page_to_virt(page);
-               memcpy(gdt, boot_cpu_compat_gdt_table,
-                      NR_RESERVED_GDT_PAGES * PAGE_SIZE);
-               gdt[PER_CPU_GDT_ENTRY - FIRST_RESERVED_GDT_ENTRY].a = cpu;
-               page = alloc_domheap_pages(NULL, order,
-                                          MEMF_node(cpu_to_node(cpu)));
-               per_cpu(gdt_table, cpu) = gdt = page_to_virt(page);
+        page = alloc_domheap_pages(NULL, order,
+                                   MEMF_node(cpu_to_node(cpu)));
+        per_cpu(compat_gdt_table, cpu) = gdt = page_to_virt(page);
+        memcpy(gdt, boot_cpu_compat_gdt_table,
+               NR_RESERVED_GDT_PAGES * PAGE_SIZE);
+        gdt[PER_CPU_GDT_ENTRY - FIRST_RESERVED_GDT_ENTRY].a = cpu;
+        page = alloc_domheap_pages(NULL, order,
+                                   MEMF_node(cpu_to_node(cpu)));
+        per_cpu(gdt_table, cpu) = gdt = page_to_virt(page);
 #else
-               per_cpu(gdt_table, cpu) = gdt = alloc_xenheap_pages(order, 0);
+        per_cpu(gdt_table, cpu) = gdt = alloc_xenheap_pages(order, 0);
 #endif
-               memcpy(gdt, boot_cpu_gdt_table,
-                      NR_RESERVED_GDT_PAGES * PAGE_SIZE);
-               BUILD_BUG_ON(NR_CPUS > 0x10000);
-               gdt[PER_CPU_GDT_ENTRY - FIRST_RESERVED_GDT_ENTRY].a = cpu;
-       }
+        memcpy(gdt, boot_cpu_gdt_table,
+               NR_RESERVED_GDT_PAGES * PAGE_SIZE);
+        BUILD_BUG_ON(NR_CPUS > 0x10000);
+        gdt[PER_CPU_GDT_ENTRY - FIRST_RESERVED_GDT_ENTRY].a = cpu;
+    }
 
 #ifdef __i386__
-       if (!per_cpu(doublefault_tss, cpu)) {
-               per_cpu(doublefault_tss, cpu) = alloc_xenheap_page();
-               memset(per_cpu(doublefault_tss, cpu), 0, PAGE_SIZE);
-       }
+    if ( !per_cpu(doublefault_tss, cpu) )
+    {
+        per_cpu(doublefault_tss, cpu) = alloc_xenheap_page();
+        memset(per_cpu(doublefault_tss, cpu), 0, PAGE_SIZE);
+    }
 #else
-       if (!per_cpu(compat_arg_xlat, cpu))
-               setup_compat_arg_xlat(cpu, cpu_to_node[cpu]);
+    if ( !per_cpu(compat_arg_xlat, cpu) )
+        setup_compat_arg_xlat(cpu, cpu_to_node[cpu]);
 #endif
 
-       if (!idt_tables[cpu]) {
-               idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
-               memcpy(idt_tables[cpu], idt_table,
-                      IDT_ENTRIES*sizeof(idt_entry_t));
-       }
-
-       /*
-        * This grunge runs the startup process for
-        * the targeted processor.
-        */
-
-       atomic_set(&init_deasserted, 0);
-
-       Dprintk("Setting warm reset code and vector.\n");
-
-       store_NMI_vector(&nmi_high, &nmi_low);
-
-       smpboot_setup_warm_reset_vector(start_eip);
-
-       /*
-        * Starting actual IPI sequence...
-        */
-       boot_error = wakeup_secondary_cpu(apicid, start_eip);
-
-       if (!boot_error) {
-               /*
-                * allow APs to start initializing.
-                */
-               Dprintk("Before Callout %d.\n", cpu);
-               cpu_set(cpu, cpu_callout_map);
-               Dprintk("After Callout %d.\n", cpu);
-
-               /*
-                * Wait 5s total for a response
-                */
-               for (timeout = 0; timeout < 50000; timeout++) {
-                       if (cpu_isset(cpu, cpu_callin_map))
-                               break;  /* It has booted */
-                       udelay(100);
-               }
-
-               if (cpu_isset(cpu, cpu_callin_map)) {
-                       /* number CPUs logically, starting from 1 (BSP is 0) */
-                       Dprintk("OK.\n");
-                       print_cpu_info(cpu);
-                       Dprintk("CPU has booted.\n");
-               } else {
-                       boot_error = 1;
-                       mb();
-                       if (bootsym(trampoline_cpu_started) == 0xA5)
-                               /* trampoline started but...? */
-                               printk("Stuck ??\n");
-                       else
-                               /* trampoline code not run */
-                               printk("Not responding.\n");
-                       inquire_remote_apic(apicid);
-               }
-       }
-
-       if (boot_error) {
-               /* Try to put things back the way they were before ... */
-               unmap_cpu_to_logical_apicid(cpu);
-               cpu_clear(cpu, cpu_callout_map); /* was set here */
-               cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
-
-               /* Mark the CPU as non-present */
-               x86_cpu_to_apicid[cpu] = BAD_APICID;
-               cpu_clear(cpu, cpu_present_map);
-       }
-
-       /* mark "stuck" area as not stuck */
-       bootsym(trampoline_cpu_started) = 0;
-       mb();
-
-       smpboot_restore_warm_reset_vector();
-
-       return boot_error ? -EIO : 0;
+    if ( !idt_tables[cpu] )
+    {
+        idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
+        memcpy(idt_tables[cpu], idt_table,
+               IDT_ENTRIES*sizeof(idt_entry_t));
+    }
+
+    /* This grunge runs the startup process for the targeted processor. */
+
+    atomic_set(&init_deasserted, 0);
+
+    Dprintk("Setting warm reset code and vector.\n");
+
+    smpboot_setup_warm_reset_vector(start_eip);
+
+    /* Starting actual IPI sequence... */
+    boot_error = wakeup_secondary_cpu(apicid, start_eip);
+
+    if ( !boot_error )
+    {
+        /* Allow AP to start initializing. */
+        Dprintk("Before Callout %d.\n", cpu);
+        cpu_set(cpu, cpu_callout_map);
+        Dprintk("After Callout %d.\n", cpu);
+
+        /* Wait 5s total for a response. */
+        for ( timeout = 0; timeout < 50000; timeout++ )
+        {
+            if ( cpu_isset(cpu, cpu_callin_map) )
+                break; /* It has booted */
+            udelay(100);
+        }
+
+        if ( cpu_isset(cpu, cpu_callin_map) )
+        {
+            /* number CPUs logically, starting from 1 (BSP is 0) */
+            Dprintk("OK.\n");
+            print_cpu_info(cpu);
+            Dprintk("CPU has booted.\n");
+        }
+        else
+        {
+            boot_error = 1;
+            mb();
+            if ( bootsym(trampoline_cpu_started) == 0xA5 )
+                /* trampoline started but...? */
+                printk("Stuck ??\n");
+            else
+                /* trampoline code not run */
+                printk("Not responding.\n");
+            inquire_remote_apic(apicid);
+        }
+    }
+
+    if ( boot_error )
+    {
+        /* Try to put things back the way they were before ... */
+        unmap_cpu_to_logical_apicid(cpu);
+        cpu_clear(cpu, cpu_callout_map); /* was set here */
+        cpu_uninit(cpu); /* undoes cpu_init() */
+
+        /* Mark the CPU as non-present */
+        x86_cpu_to_apicid[cpu] = BAD_APICID;
+        cpu_clear(cpu, cpu_present_map);
+    }
+
+    /* mark "stuck" area as not stuck */
+    bootsym(trampoline_cpu_started) = 0;
+    mb();
+
+    smpboot_restore_warm_reset_vector();
+
+    return boot_error ? -EIO : 0;
 }
 
 void cpu_exit_clear(void)
 {
-       int cpu = raw_smp_processor_id();
-
-       cpu_uninit();
-
-       cpu_clear(cpu, cpu_callout_map);
-       cpu_clear(cpu, cpu_callin_map);
-
-       cpu_clear(cpu, smp_commenced_mask);
-       unmap_cpu_to_logical_apicid(cpu);
+    int cpu = raw_smp_processor_id();
+
+    cpu_uninit(cpu);
+
+    cpu_clear(cpu, cpu_callout_map);
+    cpu_clear(cpu, cpu_callin_map);
+
+    cpu_clear(cpu, smp_commenced_mask);
+    unmap_cpu_to_logical_apicid(cpu);
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-       mtrr_aps_sync_begin();
-
-       /*
-        * Setup boot CPU information
-        */
-       smp_store_cpu_info(0); /* Final full version of the data */
-       print_cpu_info(0);
-
-       boot_cpu_physical_apicid = get_apic_id();
-       x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
-
-       stack_base[0] = stack_start.esp;
-
-       set_cpu_sibling_map(0);
-
-       /*
-        * If we couldn't find an SMP configuration at boot time,
-        * get out of here now!
-        */
-       if (!smp_found_config && !acpi_lapic) {
-               printk(KERN_NOTICE "SMP motherboard not detected.\n");
-       init_uniprocessor:
-               phys_cpu_present_map = physid_mask_of_physid(0);
-               if (APIC_init_uniprocessor())
-                       printk(KERN_NOTICE "Local APIC not detected."
-                                          " Using dummy APIC emulation.\n");
-               map_cpu_to_logical_apicid();
-               cpu_set(0, per_cpu(cpu_sibling_map, 0));
-               cpu_set(0, per_cpu(cpu_core_map, 0));
-               return;
-       }
-
-       /*
-        * Should not be necessary because the MP table should list the boot
-        * CPU too, but we do it for the sake of robustness anyway.
-        * Makes no sense to do this check in clustered apic mode, so skip it
-        */
-       if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
-               printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
-                               boot_cpu_physical_apicid);
-               physid_set(hard_smp_processor_id(), phys_cpu_present_map);
-       }
-
-       /*
-        * If we couldn't find a local APIC, then get out of here now!
-        */
-       if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])
-           && !cpu_has_apic) {
-               printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
-                       boot_cpu_physical_apicid);
-               goto init_uniprocessor;
-       }
-
-       verify_local_APIC();
-
-       connect_bsp_APIC();
-       setup_local_APIC();
-       map_cpu_to_logical_apicid();
-
-       /*
-        * construct cpu_sibling_map, so that we can tell sibling CPUs
-        * efficiently.
-        */
-       cpu_set(0, per_cpu(cpu_sibling_map, 0));
-       cpu_set(0, per_cpu(cpu_core_map, 0));
-
-       smpboot_setup_io_apic();
-
-       setup_boot_APIC_clock();
+    mtrr_aps_sync_begin();
+
+    /* Setup boot CPU information */
+    smp_store_cpu_info(0); /* Final full version of the data */
+    print_cpu_info(0);
+
+    boot_cpu_physical_apicid = get_apic_id();
+    x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
+
+    stack_base[0] = stack_start.esp;
+
+    set_cpu_sibling_map(0);
+
+    /*
+     * If we couldn't find an SMP configuration at boot time,
+     * get out of here now!
+     */
+    if ( !smp_found_config && !acpi_lapic )
+    {
+        printk(KERN_NOTICE "SMP motherboard not detected.\n");
+    init_uniprocessor:
+        phys_cpu_present_map = physid_mask_of_physid(0);
+        if (APIC_init_uniprocessor())
+            printk(KERN_NOTICE "Local APIC not detected."
+                   " Using dummy APIC emulation.\n");
+        map_cpu_to_logical_apicid();
+        cpu_set(0, per_cpu(cpu_sibling_map, 0));
+        cpu_set(0, per_cpu(cpu_core_map, 0));
+        return;
+    }
+
+    /*
+     * Should not be necessary because the MP table should list the boot
+     * CPU too, but we do it for the sake of robustness anyway.
+     * Makes no sense to do this check in clustered apic mode, so skip it
+     */
+    if ( !check_phys_apicid_present(boot_cpu_physical_apicid) )
+    {
+        printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
+               boot_cpu_physical_apicid);
+        physid_set(hard_smp_processor_id(), phys_cpu_present_map);
+    }
+
+    /* If we couldn't find a local APIC, then get out of here now! */
+    if ( APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])
+         && !cpu_has_apic )
+    {
+        printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
+               boot_cpu_physical_apicid);
+        goto init_uniprocessor;
+    }
+
+    verify_local_APIC();
+
+    connect_bsp_APIC();
+    setup_local_APIC();
+    map_cpu_to_logical_apicid();
+
+    /*
+     * construct cpu_sibling_map, so that we can tell sibling CPUs
+     * efficiently.
+     */
+    cpu_set(0, per_cpu(cpu_sibling_map, 0));
+    cpu_set(0, per_cpu(cpu_core_map, 0));
+
+    smpboot_setup_io_apic();
+
+    setup_boot_APIC_clock();
 }
 
 void __init smp_prepare_boot_cpu(void)
 {
-       cpu_set(smp_processor_id(), smp_commenced_mask);
-       cpu_set(smp_processor_id(), cpu_callin_map);
-       cpu_set(smp_processor_id(), cpu_online_map);
-       cpu_set(smp_processor_id(), cpu_callout_map);
-       cpu_set(smp_processor_id(), cpu_present_map);
-       cpu_set(smp_processor_id(), cpu_possible_map);
-       per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+    cpu_set(smp_processor_id(), smp_commenced_mask);
+    cpu_set(smp_processor_id(), cpu_callin_map);
+    cpu_set(smp_processor_id(), cpu_online_map);
+    cpu_set(smp_processor_id(), cpu_callout_map);
+    cpu_set(smp_processor_id(), cpu_present_map);
+    cpu_set(smp_processor_id(), cpu_possible_map);
+    per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 }
 
 static void
 remove_siblinginfo(int cpu)
 {
-       int sibling;
-       struct cpuinfo_x86 *c = cpu_data;
-
-       for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
-               cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
-               /*
-                * last thread sibling in this cpu core going down
-                */
-               if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
-                       c[sibling].booted_cores--;
-       }
-                       
-       for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
-               cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
-       cpus_clear(per_cpu(cpu_sibling_map, cpu));
-       cpus_clear(per_cpu(cpu_core_map, cpu));
-       phys_proc_id[cpu] = BAD_APICID;
-       cpu_core_id[cpu] = BAD_APICID;
-       cpu_clear(cpu, cpu_sibling_setup_map);
+    int sibling;
+    struct cpuinfo_x86 *c = cpu_data;
+
+    for_each_cpu_mask ( sibling, per_cpu(cpu_core_map, cpu) )
+    {
+        cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
+        /* Last thread sibling in this cpu core going down. */
+        if ( cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1 )
+            c[sibling].booted_cores--;
+    }
+   
+    for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
+        cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
+    cpus_clear(per_cpu(cpu_sibling_map, cpu));
+    cpus_clear(per_cpu(cpu_core_map, cpu));
+    phys_proc_id[cpu] = BAD_APICID;
+    cpu_core_id[cpu] = BAD_APICID;
+    cpu_clear(cpu, cpu_sibling_setup_map);
 }
 
 void __cpu_disable(void)
 {
-       extern void fixup_irqs(void);
-       int cpu = smp_processor_id();
-
-       local_irq_disable();
-       clear_local_APIC();
-       /* Allow any queued timer interrupts to get serviced */
-       local_irq_enable();
-       mdelay(1);
-       local_irq_disable();
-
-       time_suspend();
-
-       remove_siblinginfo(cpu);
-
-       /* It's now safe to remove this processor from the online map */
-       cpu_clear(cpu, cpupool0->cpu_valid);
-       cpu_clear(cpu, cpu_online_map);
-       fixup_irqs();
-
-       cpu_disable_scheduler(cpu);
+    extern void fixup_irqs(void);
+    int cpu = smp_processor_id();
+
+    local_irq_disable();
+    clear_local_APIC();
+    /* Allow any queued timer interrupts to get serviced */
+    local_irq_enable();
+    mdelay(1);
+    local_irq_disable();
+
+    time_suspend();
+
+    remove_siblinginfo(cpu);
+
+    /* It's now safe to remove this processor from the online map */
+    cpu_clear(cpu, cpupool0->cpu_valid);
+    cpu_clear(cpu, cpu_online_map);
+    fixup_irqs();
+
+    cpu_disable_scheduler(cpu);
 }
 
 void __cpu_die(unsigned int cpu)
 {
-       /* We don't do anything here: idle task is faking death itself. */
-       unsigned int i = 0;
-
-       for (;;) {
-               /* They ack this in play_dead by setting CPU_DEAD */
-               if (per_cpu(cpu_state, cpu) == CPU_DEAD)
-                       break;
-               mdelay(100);
-               cpu_relax();
-               process_pending_softirqs();
-               if ((++i % 10) == 0)
-                       printk(KERN_ERR "CPU %u still not dead...\n", cpu);
-       }
+    /* We don't do anything here: idle task is faking death itself. */
+    unsigned int i = 0;
+
+    while ( per_cpu(cpu_state, cpu) != CPU_DEAD )
+    {
+        mdelay(100);
+        cpu_relax();
+        process_pending_softirqs();
+        if ( (++i % 10) == 0 )
+            printk(KERN_ERR "CPU %u still not dead...\n", cpu);
+    }
 }
 
 int cpu_add(uint32_t apic_id, uint32_t acpi_id, uint32_t pxm)
 {
-       int node, cpu = -1;
-
-       dprintk(XENLOG_DEBUG, "cpu_add apic_id %x acpi_id %x pxm %x\n",
-               apic_id, acpi_id, pxm);
-
-       if ( acpi_id > MAX_MADT_ENTRIES || apic_id > MAX_APICS || pxm > 256 )
-               return -EINVAL;
-
-       if ( !cpu_hotplug_begin() )
-               return -EBUSY;
-
-       /* Detect if the cpu has been added before */
-       if ( x86_acpiid_to_apicid[acpi_id] != 0xff )
-       {
-               cpu = (x86_acpiid_to_apicid[acpi_id] != apic_id)
-                       ? -EINVAL : -EEXIST;
-               goto out;
-       }
-
-       if ( physid_isset(apic_id, phys_cpu_present_map) )
-       {
-               cpu = -EEXIST;
-               goto out;
-       }
-
-       if ( (cpu = mp_register_lapic(apic_id, 1)) < 0 )
-               goto out;
-
-       x86_acpiid_to_apicid[acpi_id] = apic_id;
-
-       if ( !srat_disabled() )
-       {
-               if ( (node = setup_node(pxm)) < 0 )
-               {
-                       dprintk(XENLOG_WARNING,
-                               "Setup node failed for pxm %x\n", pxm);
-                       x86_acpiid_to_apicid[acpi_id] = 0xff;
-                       mp_unregister_lapic(apic_id, cpu);
-                       cpu = node;
-                       goto out;
-               }
-               apicid_to_node[apic_id] = node;
-       }
-
-       srat_detect_node(cpu);
-       numa_add_cpu(cpu);
-       dprintk(XENLOG_INFO, "Add CPU %x with index %x\n", apic_id, cpu);
+    int node, cpu = -1;
+
+    dprintk(XENLOG_DEBUG, "cpu_add apic_id %x acpi_id %x pxm %x\n",
+            apic_id, acpi_id, pxm);
+
+    if ( acpi_id > MAX_MADT_ENTRIES || apic_id > MAX_APICS || pxm > 256 )
+        return -EINVAL;
+
+    if ( !cpu_hotplug_begin() )
+        return -EBUSY;
+
+    /* Detect if the cpu has been added before */
+    if ( x86_acpiid_to_apicid[acpi_id] != 0xff )
+    {
+        cpu = (x86_acpiid_to_apicid[acpi_id] != apic_id)
+            ? -EINVAL : -EEXIST;
+        goto out;
+    }
+
+    if ( physid_isset(apic_id, phys_cpu_present_map) )
+    {
+        cpu = -EEXIST;
+        goto out;
+    }
+
+    if ( (cpu = mp_register_lapic(apic_id, 1)) < 0 )
+        goto out;
+
+    x86_acpiid_to_apicid[acpi_id] = apic_id;
+
+    if ( !srat_disabled() )
+    {
+        if ( (node = setup_node(pxm)) < 0 )
+        {
+            dprintk(XENLOG_WARNING,
+                    "Setup node failed for pxm %x\n", pxm);
+            x86_acpiid_to_apicid[acpi_id] = 0xff;
+            mp_unregister_lapic(apic_id, cpu);
+            cpu = node;
+            goto out;
+        }
+        apicid_to_node[apic_id] = node;
+    }
+
+    srat_detect_node(cpu);
+    numa_add_cpu(cpu);
+    dprintk(XENLOG_INFO, "Add CPU %x with index %x\n", apic_id, cpu);
  out:
-       cpu_hotplug_done();
-       return cpu;
+    cpu_hotplug_done();
+    return cpu;
 }
 
 
 int __cpu_up(unsigned int cpu)
 {
-       int apicid, ret;
-
-       BUG_ON(cpu_isset(cpu, cpu_callin_map));
-
-       if ((apicid = x86_cpu_to_apicid[cpu]) == BAD_APICID)
-               return -ENODEV;
-
-       if ((ret = do_boot_cpu(apicid, cpu)) != 0)
-           return ret;
-
-       cpu_set(cpu, smp_commenced_mask);
-       while (!cpu_isset(cpu, cpu_online_map)) {
-               cpu_relax();
-               process_pending_softirqs();
-       }
-
-       return 0;
+    int apicid, ret;
+
+    BUG_ON(cpu_isset(cpu, cpu_callin_map));
+
+    if ( (apicid = x86_cpu_to_apicid[cpu]) == BAD_APICID )
+        return -ENODEV;
+
+    if ( (ret = do_boot_cpu(apicid, cpu)) != 0 )
+        return ret;
+
+    cpu_set(cpu, smp_commenced_mask);
+    while ( !cpu_isset(cpu, cpu_online_map) )
+    {
+        cpu_relax();
+        process_pending_softirqs();
+    }
+
+    return 0;
 }
 
 
 void __init smp_cpus_done(unsigned int max_cpus)
 {
-       if (smp_b_stepping)
-               printk(KERN_WARNING "WARNING: SMP operation may be "
-                      "unreliable with B stepping processors.\n");
-
-       /*
-        * Don't taint if we are running SMP kernel on a single non-MP
-        * approved Athlon
-        */
-       if (tainted & TAINT_UNSAFE_SMP) {
-               if (num_online_cpus() > 1)
-                       printk(KERN_INFO "WARNING: This combination of AMD "
-                              "processors is not suitable for SMP.\n");
-               else
-                       tainted &= ~TAINT_UNSAFE_SMP;
-       }
-
-       if (nmi_watchdog == NMI_LOCAL_APIC)
-               check_nmi_watchdog();
-
-       setup_ioapic_dest();
-
-       mtrr_save_state();
-       mtrr_aps_sync_end();
+    if ( smp_b_stepping )
+        printk(KERN_WARNING "WARNING: SMP operation may be "
+               "unreliable with B stepping processors.\n");
+
+    /*
+     * Don't taint if we are running SMP kernel on a single non-MP
+     * approved Athlon
+     */
+    if ( tainted & TAINT_UNSAFE_SMP )
+    {
+        if ( num_online_cpus() > 1 )
+            printk(KERN_INFO "WARNING: This combination of AMD "
+                   "processors is not suitable for SMP.\n");
+        else
+            tainted &= ~TAINT_UNSAFE_SMP;
+    }
+
+    if ( nmi_watchdog == NMI_LOCAL_APIC )
+        check_nmi_watchdog();
+
+    setup_ioapic_dest();
+
+    mtrr_save_state();
+    mtrr_aps_sync_end();
 }
 
 void __init smp_intr_init(void)
 {
-       int irq, seridx, cpu = smp_processor_id();
-
-       /*
-        * IRQ0 must be given a fixed assignment and initialized,
-        * because it's used before the IO-APIC is set up.
-        */
-       irq_vector[0] = FIRST_HIPRIORITY_VECTOR;
-
-       /*
-        * Also ensure serial interrupts are high priority. We do not
-        * want them to be blocked by unacknowledged guest-bound interrupts.
-        */
-       for (seridx = 0; seridx < 2; seridx++) {
-               if ((irq = serial_irq(seridx)) < 0)
-                       continue;
-               irq_vector[irq] = FIRST_HIPRIORITY_VECTOR + seridx + 1;
-               per_cpu(vector_irq, cpu)[FIRST_HIPRIORITY_VECTOR + seridx + 1] 
= irq;
-               irq_cfg[irq].vector = FIRST_HIPRIORITY_VECTOR + seridx + 1;
-               irq_cfg[irq].domain = (cpumask_t)CPU_MASK_ALL;
-       }
-
-       /* IPI for cleanuping vectors after irq move */
-       set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
-
-       /* IPI for event checking. */
-       set_intr_gate(EVENT_CHECK_VECTOR, event_check_interrupt);
-
-       /* IPI for invalidation */
-       set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
-
-       /* IPI for generic function call */
-       set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
-}
+    int irq, seridx, cpu = smp_processor_id();
+
+    /*
+     * IRQ0 must be given a fixed assignment and initialized,
+     * because it's used before the IO-APIC is set up.
+     */
+    irq_vector[0] = FIRST_HIPRIORITY_VECTOR;
+
+    /*
+     * Also ensure serial interrupts are high priority. We do not
+     * want them to be blocked by unacknowledged guest-bound interrupts.
+     */
+    for ( seridx = 0; seridx < 2; seridx++ )
+    {
+        if ( (irq = serial_irq(seridx)) < 0 )
+            continue;
+        irq_vector[irq] = FIRST_HIPRIORITY_VECTOR + seridx + 1;
+        per_cpu(vector_irq, cpu)[FIRST_HIPRIORITY_VECTOR + seridx + 1] = irq;
+        irq_cfg[irq].vector = FIRST_HIPRIORITY_VECTOR + seridx + 1;
+        irq_cfg[irq].domain = (cpumask_t)CPU_MASK_ALL;
+    }
+
+    /* IPI for cleanuping vectors after irq move */
+    set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
+
+    /* IPI for event checking. */
+    set_intr_gate(EVENT_CHECK_VECTOR, event_check_interrupt);
+
+    /* IPI for invalidation */
+    set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
+
+    /* IPI for generic function call */
+    set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
+}
diff -r c7dde06ba1c3 -r 89a2f9ad02f2 
xen/include/asm-x86/mach-default/mach_wakecpu.h
--- a/xen/include/asm-x86/mach-default/mach_wakecpu.h   Mon May 17 16:28:56 
2010 +0100
+++ b/xen/include/asm-x86/mach-default/mach_wakecpu.h   Mon May 17 16:58:24 
2010 +0100
@@ -24,14 +24,6 @@ static inline void smp_callin_clear_loca
 {
 }
 
-static inline void store_NMI_vector(unsigned short *high, unsigned short *low)
-{
-}
-
-static inline void restore_NMI_vector(unsigned short *high, unsigned short 
*low)
-{
-}
-
 #if APIC_DEBUG
  #define inquire_remote_apic(apicid) __inquire_remote_apic(apicid)
 #else
diff -r c7dde06ba1c3 -r 89a2f9ad02f2 xen/include/asm-x86/smp.h
--- a/xen/include/asm-x86/smp.h Mon May 17 16:28:56 2010 +0100
+++ b/xen/include/asm-x86/smp.h Mon May 17 16:58:24 2010 +0100
@@ -57,7 +57,7 @@ DECLARE_PER_CPU(int, cpu_state);
 
 #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))
 extern void cpu_exit_clear(void);
-extern void cpu_uninit(void);
+extern void cpu_uninit(unsigned int cpu);
 int cpu_add(uint32_t apic_id, uint32_t acpi_id, uint32_t pxm);
 
 /*

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.