aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/setup.c
diff options
context:
space:
mode:
authorSiddha, Suresh B <suresh.b.siddha@intel.com>2005-11-05 11:25:54 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-14 22:55:16 -0500
commit94605eff572b727aaad9b4b29bc358b919096503 (patch)
tree657a848d8ef34d2f94bbad3aa4e5458d2d3f2d2b /arch/x86_64/kernel/setup.c
parente90f22edf432512219cc2952f5811961abbd164f (diff)
[PATCH] x86-64/i386: Intel HT, Multi core detection fixes
Fields obtained through cpuid vector 0x1(ebx[16:23]) and vector 0x4(eax[14:25], eax[26:31]) indicate the maximum values and might not always be the same as what is available and what OS sees. So make sure "siblings" and "cpu cores" values in /proc/cpuinfo reflect the values as seen by OS instead of what cpuid instruction says. This will also fix the buggy BIOS cases (for example where cpuid on a single core cpu says there are "2" siblings, even when HT is disabled in the BIOS. http://bugzilla.kernel.org/show_bug.cgi?id=4359) Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/setup.c')
-rw-r--r--arch/x86_64/kernel/setup.c69
1 files changed, 29 insertions, 40 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 476ee034fca2..40c77f6fe4b0 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -795,7 +795,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
795#endif 795#endif
796 796
797 bits = 0; 797 bits = 0;
798 while ((1 << bits) < c->x86_num_cores) 798 while ((1 << bits) < c->x86_max_cores)
799 bits++; 799 bits++;
800 800
801 /* Low order bits define the core id (index of core in socket) */ 801 /* Low order bits define the core id (index of core in socket) */
@@ -828,7 +828,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
828 numa_set_node(cpu, node); 828 numa_set_node(cpu, node);
829 829
830 printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", 830 printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
831 cpu, c->x86_num_cores, node, cpu_core_id[cpu]); 831 cpu, c->x86_max_cores, node, cpu_core_id[cpu]);
832#endif 832#endif
833#endif 833#endif
834} 834}
@@ -877,9 +877,9 @@ static int __init init_amd(struct cpuinfo_x86 *c)
877 display_cacheinfo(c); 877 display_cacheinfo(c);
878 878
879 if (c->extended_cpuid_level >= 0x80000008) { 879 if (c->extended_cpuid_level >= 0x80000008) {
880 c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; 880 c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
881 if (c->x86_num_cores & (c->x86_num_cores - 1)) 881 if (c->x86_max_cores & (c->x86_max_cores - 1))
882 c->x86_num_cores = 1; 882 c->x86_max_cores = 1;
883 883
884 amd_detect_cmp(c); 884 amd_detect_cmp(c);
885 } 885 }
@@ -891,54 +891,44 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
891{ 891{
892#ifdef CONFIG_SMP 892#ifdef CONFIG_SMP
893 u32 eax, ebx, ecx, edx; 893 u32 eax, ebx, ecx, edx;
894 int index_msb, tmp; 894 int index_msb, core_bits;
895 int cpu = smp_processor_id(); 895 int cpu = smp_processor_id();
896 896
897 cpuid(1, &eax, &ebx, &ecx, &edx);
898
899 c->apicid = phys_pkg_id(0);
900
897 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) 901 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
898 return; 902 return;
899 903
900 cpuid(1, &eax, &ebx, &ecx, &edx);
901 smp_num_siblings = (ebx & 0xff0000) >> 16; 904 smp_num_siblings = (ebx & 0xff0000) >> 16;
902 905
903 if (smp_num_siblings == 1) { 906 if (smp_num_siblings == 1) {
904 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); 907 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
905 } else if (smp_num_siblings > 1) { 908 } else if (smp_num_siblings > 1 ) {
906 index_msb = 31; 909
907 /*
908 * At this point we only support two siblings per
909 * processor package.
910 */
911 if (smp_num_siblings > NR_CPUS) { 910 if (smp_num_siblings > NR_CPUS) {
912 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); 911 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
913 smp_num_siblings = 1; 912 smp_num_siblings = 1;
914 return; 913 return;
915 } 914 }
916 tmp = smp_num_siblings; 915
917 while ((tmp & 0x80000000 ) == 0) { 916 index_msb = get_count_order(smp_num_siblings);
918 tmp <<=1 ;
919 index_msb--;
920 }
921 if (smp_num_siblings & (smp_num_siblings - 1))
922 index_msb++;
923 phys_proc_id[cpu] = phys_pkg_id(index_msb); 917 phys_proc_id[cpu] = phys_pkg_id(index_msb);
924 918
925 printk(KERN_INFO "CPU: Physical Processor ID: %d\n", 919 printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
926 phys_proc_id[cpu]); 920 phys_proc_id[cpu]);
927 921
928 smp_num_siblings = smp_num_siblings / c->x86_num_cores; 922 smp_num_siblings = smp_num_siblings / c->x86_max_cores;
929 923
930 tmp = smp_num_siblings; 924 index_msb = get_count_order(smp_num_siblings) ;
931 index_msb = 31; 925
932 while ((tmp & 0x80000000) == 0) { 926 core_bits = get_count_order(c->x86_max_cores);
933 tmp <<=1 ;
934 index_msb--;
935 }
936 if (smp_num_siblings & (smp_num_siblings - 1))
937 index_msb++;
938 927
939 cpu_core_id[cpu] = phys_pkg_id(index_msb); 928 cpu_core_id[cpu] = phys_pkg_id(index_msb) &
929 ((1 << core_bits) - 1);
940 930
941 if (c->x86_num_cores > 1) 931 if (c->x86_max_cores > 1)
942 printk(KERN_INFO "CPU: Processor Core ID: %d\n", 932 printk(KERN_INFO "CPU: Processor Core ID: %d\n",
943 cpu_core_id[cpu]); 933 cpu_core_id[cpu]);
944 } 934 }
@@ -1006,7 +996,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
1006 c->x86_cache_alignment = c->x86_clflush_size * 2; 996 c->x86_cache_alignment = c->x86_clflush_size * 2;
1007 if (c->x86 >= 15) 997 if (c->x86 >= 15)
1008 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); 998 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
1009 c->x86_num_cores = intel_num_cpu_cores(c); 999 c->x86_max_cores = intel_num_cpu_cores(c);
1010 1000
1011 srat_detect_node(); 1001 srat_detect_node();
1012} 1002}
@@ -1044,7 +1034,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
1044 c->x86_model_id[0] = '\0'; /* Unset */ 1034 c->x86_model_id[0] = '\0'; /* Unset */
1045 c->x86_clflush_size = 64; 1035 c->x86_clflush_size = 64;
1046 c->x86_cache_alignment = c->x86_clflush_size; 1036 c->x86_cache_alignment = c->x86_clflush_size;
1047 c->x86_num_cores = 1; 1037 c->x86_max_cores = 1;
1048 c->extended_cpuid_level = 0; 1038 c->extended_cpuid_level = 0;
1049 memset(&c->x86_capability, 0, sizeof c->x86_capability); 1039 memset(&c->x86_capability, 0, sizeof c->x86_capability);
1050 1040
@@ -1278,13 +1268,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1278 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); 1268 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
1279 1269
1280#ifdef CONFIG_SMP 1270#ifdef CONFIG_SMP
1281 if (smp_num_siblings * c->x86_num_cores > 1) { 1271 if (smp_num_siblings * c->x86_max_cores > 1) {
1282 int cpu = c - cpu_data; 1272 int cpu = c - cpu_data;
1283 seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]); 1273 seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]);
1284 seq_printf(m, "siblings\t: %d\n", 1274 seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu]));
1285 c->x86_num_cores * smp_num_siblings);
1286 seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]); 1275 seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]);
1287 seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores); 1276 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
1288 } 1277 }
1289#endif 1278#endif
1290 1279