Pull xpc-disengage into release branch
[sfrench/cifs-2.6.git] / arch / x86_64 / kernel / setup.c
index 9aec524be3ebbbb653bcd32b42e44ea51324f442..cb28df14ff6fea87991daba07241b86835db30ee 100644 (file)
@@ -336,6 +336,11 @@ static __init void parse_cmdline_early (char ** cmdline_p)
 #endif
 #endif
 
+               if (!memcmp(from, "disable_timer_pin_1", 19))
+                       disable_timer_pin_1 = 1;
+               if (!memcmp(from, "enable_timer_pin_1", 18))
+                       disable_timer_pin_1 = -1;
+
                if (!memcmp(from, "nolapic", 7) ||
                    !memcmp(from, "disableapic", 11))
                        disable_apic = 1;
@@ -755,6 +760,24 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
        }
 }
 
+#ifdef CONFIG_NUMA
+static int nearby_node(int apicid)
+{
+       int i;
+       for (i = apicid - 1; i >= 0; i--) {
+               int node = apicid_to_node[i];
+               if (node != NUMA_NO_NODE && node_online(node))
+                       return node;
+       }
+       for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
+               int node = apicid_to_node[i];
+               if (node != NUMA_NO_NODE && node_online(node))
+                       return node;
+       }
+       return first_node(node_online_map); /* Shouldn't happen */
+}
+#endif
+
 /*
  * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
  * Assumes number of cores is a power of two.
@@ -763,8 +786,11 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
        int cpu = smp_processor_id();
-       int node = 0;
        unsigned bits;
+#ifdef CONFIG_NUMA
+       int node = 0;
+       unsigned apicid = phys_proc_id[cpu];
+#endif
 
        bits = 0;
        while ((1 << bits) < c->x86_num_cores)
@@ -776,20 +802,32 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
        phys_proc_id[cpu] >>= bits;
 
 #ifdef CONFIG_NUMA
-       /* When an ACPI SRAT table is available use the mappings from SRAT
-          instead. */
-       if (acpi_numa <= 0) {
-               node = phys_proc_id[cpu];
-               if (!node_online(node))
-                       node = first_node(node_online_map);
-               cpu_to_node[cpu] = node;
-       } else {
-               node = cpu_to_node[cpu];
-       }
+       node = phys_proc_id[cpu];
+       if (apicid_to_node[apicid] != NUMA_NO_NODE)
+               node = apicid_to_node[apicid];
+       if (!node_online(node)) {
+               /* Two possibilities here:
+                  - The CPU is missing memory and no node was created.
+                  In that case try picking one from a nearby CPU
+                  - The APIC IDs differ from the HyperTransport node IDs
+                  which the K8 northbridge parsing fills in.
+                  Assume they are all increased by a constant offset,
+                  but in the same order as the HT nodeids.
+                  If that doesn't result in a usable node fall back to the
+                  path for the previous case.  */
+               int ht_nodeid = apicid - (phys_proc_id[0] << bits);
+               if (ht_nodeid >= 0 &&
+                   apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
+                       node = apicid_to_node[ht_nodeid];
+               /* Pick a nearby node */
+               if (!node_online(node))
+                       node = nearby_node(apicid);
+       }
+       cpu_to_node[cpu] = node;
+
+       printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
+                       cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
 #endif
-
-       printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
-                       cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
 #endif
 }
 
@@ -798,6 +836,23 @@ static int __init init_amd(struct cpuinfo_x86 *c)
        int r;
        int level;
 
+#ifdef CONFIG_SMP
+       unsigned long value;
+
+       /*
+        * Disable TLB flush filter by setting HWCR.FFDIS on K8
+        * bit 6 of msr C001_0015
+        *
+        * Errata 63 for SH-B3 steppings
+        * Errata 122 for all steppings (F+ have it disabled by default)
+        */
+       if (c->x86 == 15) {
+               rdmsrl(MSR_K8_HWCR, value);
+               value |= 1 << 6;
+               wrmsrl(MSR_K8_HWCR, value);
+       }
+#endif
+
        /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
           3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
        clear_bit(0*32+31, &c->x86_capability);
@@ -909,6 +964,24 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
                return 1;
 }
 
+static void srat_detect_node(void)
+{
+#ifdef CONFIG_NUMA
+       unsigned node;
+       int cpu = smp_processor_id();
+
+       /* Don't do the funky fallback heuristics the AMD version employs
+          for now. */
+       node = apicid_to_node[hard_smp_processor_id()];
+       if (node == NUMA_NO_NODE)
+               node = 0;
+       cpu_to_node[cpu] = node;
+
+       if (acpi_numa > 0)
+               printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node);
+#endif
+}
+
 static void __cpuinit init_intel(struct cpuinfo_x86 *c)
 {
        /* Cache sizes */
@@ -927,6 +1000,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
        if (c->x86 >= 15)
                set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
        c->x86_num_cores = intel_num_cpu_cores(c);
+
+       srat_detect_node();
 }
 
 static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)