aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/cpu/common.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/i386/kernel/cpu/common.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/i386/kernel/cpu/common.c')
-rw-r--r--arch/i386/kernel/cpu/common.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 35a67dab4a94..4e9c2e99b0a5 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -335,7 +335,7 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
335 c->x86_model = c->x86_mask = 0; /* So far unknown... */ 335 c->x86_model = c->x86_mask = 0; /* So far unknown... */
336 c->x86_vendor_id[0] = '\0'; /* Unset */ 336 c->x86_vendor_id[0] = '\0'; /* Unset */
337 c->x86_model_id[0] = '\0'; /* Unset */ 337 c->x86_model_id[0] = '\0'; /* Unset */
338 c->x86_num_cores = 1; 338 c->x86_max_cores = 1;
339 memset(&c->x86_capability, 0, sizeof c->x86_capability); 339 memset(&c->x86_capability, 0, sizeof c->x86_capability);
340 340
341 if (!have_cpuid_p()) { 341 if (!have_cpuid_p()) {
@@ -446,52 +446,44 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
446void __devinit detect_ht(struct cpuinfo_x86 *c) 446void __devinit detect_ht(struct cpuinfo_x86 *c)
447{ 447{
448 u32 eax, ebx, ecx, edx; 448 u32 eax, ebx, ecx, edx;
449 int index_msb, tmp; 449 int index_msb, core_bits;
450 int cpu = smp_processor_id(); 450 int cpu = smp_processor_id();
451 451
452 cpuid(1, &eax, &ebx, &ecx, &edx);
453
454 c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
455
452 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) 456 if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
453 return; 457 return;
454 458
455 cpuid(1, &eax, &ebx, &ecx, &edx);
456 smp_num_siblings = (ebx & 0xff0000) >> 16; 459 smp_num_siblings = (ebx & 0xff0000) >> 16;
457 460
458 if (smp_num_siblings == 1) { 461 if (smp_num_siblings == 1) {
459 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); 462 printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
460 } else if (smp_num_siblings > 1 ) { 463 } else if (smp_num_siblings > 1 ) {
461 index_msb = 31;
462 464
463 if (smp_num_siblings > NR_CPUS) { 465 if (smp_num_siblings > NR_CPUS) {
464 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); 466 printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
465 smp_num_siblings = 1; 467 smp_num_siblings = 1;
466 return; 468 return;
467 } 469 }
468 tmp = smp_num_siblings; 470
469 while ((tmp & 0x80000000 ) == 0) { 471 index_msb = get_count_order(smp_num_siblings);
470 tmp <<=1 ;
471 index_msb--;
472 }
473 if (smp_num_siblings & (smp_num_siblings - 1))
474 index_msb++;
475 phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); 472 phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
476 473
477 printk(KERN_INFO "CPU: Physical Processor ID: %d\n", 474 printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
478 phys_proc_id[cpu]); 475 phys_proc_id[cpu]);
479 476
480 smp_num_siblings = smp_num_siblings / c->x86_num_cores; 477 smp_num_siblings = smp_num_siblings / c->x86_max_cores;
481 478
482 tmp = smp_num_siblings; 479 index_msb = get_count_order(smp_num_siblings) ;
483 index_msb = 31;
484 while ((tmp & 0x80000000) == 0) {
485 tmp <<=1 ;
486 index_msb--;
487 }
488 480
489 if (smp_num_siblings & (smp_num_siblings - 1)) 481 core_bits = get_count_order(c->x86_max_cores);
490 index_msb++;
491 482
492 cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); 483 cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) &
484 ((1 << core_bits) - 1);
493 485
494 if (c->x86_num_cores > 1) 486 if (c->x86_max_cores > 1)
495 printk(KERN_INFO "CPU: Processor Core ID: %d\n", 487 printk(KERN_INFO "CPU: Processor Core ID: %d\n",
496 cpu_core_id[cpu]); 488 cpu_core_id[cpu]);
497 } 489 }