vserver 1.9.5.x5
[linux-2.6.git] / arch / x86_64 / kernel / smpboot.c
index 4d9c47f..a7e2c3e 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/irq.h>
 #include <linux/bootmem.h>
 #include <linux/thread_info.h>
+#include <linux/module.h>
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
-char phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+/* Package ID of each logical CPU */
+u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+EXPORT_SYMBOL(phys_proc_id);
 
 /* Bitmask of currently online CPUs */
 cpumask_t cpu_online_map;
 
-/* which logical CPU number maps to which CPU (physical APIC ID) */
-volatile char x86_cpu_to_apicid[NR_CPUS];
-
-static cpumask_t cpu_callin_map;
+cpumask_t cpu_callin_map;
 cpumask_t cpu_callout_map;
 static cpumask_t smp_commenced_mask;
 
@@ -73,7 +73,7 @@ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
 /* Set when the idlers are all forked */
 int smp_threads_ready;
 
-char cpu_sibling_map[NR_CPUS] __cacheline_aligned;
+cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
 
 /*
  * Trampoline 80x86 program as an array.
@@ -390,16 +390,6 @@ void __init start_secondary(void)
 extern volatile unsigned long init_rsp; 
 extern void (*initial_code)(void);
 
-static struct task_struct * __init fork_by_hand(void)
-{
-       struct pt_regs regs;
-       /*
-        * don't care about the eip and regs settings since
-        * we'll never reschedule the forked task.
-        */
-       return copy_process(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
-}
-
 #if APIC_DEBUG
 static inline void inquire_remote_apic(int apicid)
 {
@@ -573,26 +563,17 @@ static void __init do_boot_cpu (int apicid)
         * We can't use kernel_thread since we must avoid to
         * reschedule the child.
         */
-       idle = fork_by_hand();
+       idle = fork_idle(cpu);
        if (IS_ERR(idle))
                panic("failed fork for CPU %d", cpu);
-       wake_up_forked_process(idle);   
        x86_cpu_to_apicid[cpu] = apicid;
 
-       /*
-        * We remove it from the pidhash and the runqueue
-        * once we got the process:
-        */
-       init_idle(idle,cpu);
-
-       unhash_process(idle);
-
        cpu_pda[cpu].pcurrent = idle;
 
        start_rip = setup_trampoline();
 
        init_rsp = idle->thread.rsp; 
-       init_tss[cpu].rsp0 = init_rsp;
+       per_cpu(init_tss,cpu).rsp0 = init_rsp;
        initial_code = start_secondary;
        clear_ti_thread_flag(idle->thread_info, TIF_FORK);
 
@@ -659,7 +640,7 @@ static void __init do_boot_cpu (int apicid)
                        Dprintk("CPU has booted.\n");
                } else {
                        boot_error = 1;
-                       if (*((volatile unsigned char *)phys_to_virt(8192))
+                       if (*((volatile unsigned char *)phys_to_virt(SMP_TRAMPOLINE_BASE))
                                        == 0xA5)
                                /* trampoline started but...? */
                                printk("Stuck ??\n");
@@ -675,10 +656,9 @@ static void __init do_boot_cpu (int apicid)
                cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
                clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
                cpucount--;
+               x86_cpu_to_apicid[cpu] = BAD_APICID;
+               x86_cpu_to_log_apicid[cpu] = BAD_APICID;
        }
-
-       /* mark "stuck" area as not stuck */
-       *((volatile unsigned *)phys_to_virt(8192)) = 0;
 }
 
 cycles_t cacheflush_time;
@@ -827,7 +807,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                if (apicid == boot_cpu_id || (apicid == BAD_APICID))
                        continue;
 
-               if (!cpu_isset(apicid, phys_cpu_present_map))
+               if (!physid_isset(apicid, phys_cpu_present_map))
                        continue;
                if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
                        continue;
@@ -874,31 +854,38 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        }
 
        /*
-        * If Hyper-Threading is avaialble, construct cpu_sibling_map[], so
-        * that we can tell the sibling CPU efficiently.
+        * Construct cpu_sibling_map[], so that we can tell the
+        * sibling CPU efficiently.
         */
-       if (cpu_has_ht && smp_num_siblings > 1) {
-               for (cpu = 0; cpu < NR_CPUS; cpu++)
-                       cpu_sibling_map[cpu] = NO_PROC_ID;
-               
-               for (cpu = 0; cpu < NR_CPUS; cpu++) {
-                       int     i;
-                       if (!cpu_isset(cpu, cpu_callout_map))
-                               continue;
+       for (cpu = 0; cpu < NR_CPUS; cpu++)
+               cpus_clear(cpu_sibling_map[cpu]);
+
+       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+               int siblings = 0;
+               int i;
+               if (!cpu_isset(cpu, cpu_callout_map))
+                       continue;
 
+               if (smp_num_siblings > 1) {
                        for (i = 0; i < NR_CPUS; i++) {
-                               if (i == cpu || !cpu_isset(i, cpu_callout_map))
+                               if (!cpu_isset(i, cpu_callout_map))
                                        continue;
                                if (phys_proc_id[cpu] == phys_proc_id[i]) {
-                                       cpu_sibling_map[cpu] = i;
-                                       break;
+                                       siblings++;
+                                       cpu_set(i, cpu_sibling_map[cpu]);
                                }
                        }
-                       if (cpu_sibling_map[cpu] == (char)NO_PROC_ID) {
-                               smp_num_siblings = 1;
-                               printk(KERN_WARNING "WARNING: No sibling found for CPU %d.\n", cpu);
-                       }
+               } else { 
+                       siblings++;
+                       cpu_set(cpu, cpu_sibling_map[cpu]);
                }
+
+               if (siblings != smp_num_siblings) {
+                       printk(KERN_WARNING 
+              "WARNING: %d siblings found for CPU%d, should be %d\n", 
+                              siblings, cpu, smp_num_siblings);
+                       smp_num_siblings = siblings;
+               }       
        }
 
        Dprintk("Boot done.\n");
@@ -963,6 +950,9 @@ int __devinit __cpu_up(unsigned int cpu)
 
 void __init smp_cpus_done(unsigned int max_cpus)
 {
+#ifdef CONFIG_X86_IO_APIC
+       setup_ioapic_dest();
+#endif
        zap_low_mappings();
 }