diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/arch/x86/cpu/amd.c xeno.0611/xen/arch/x86/cpu/amd.c --- xeno-today/xen/arch/x86/cpu/amd.c 2005-05-28 12:19:58.000000000 -0500 +++ xeno.0611/xen/arch/x86/cpu/amd.c 2005-06-20 07:46:38.000000000 -0500 @@ -193,7 +193,14 @@ static void __init init_amd(struct cpuin } display_cacheinfo(c); - detect_ht(c); + + if (cpuid_eax(0x80000000) >= 0x80000008) { + c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; + if (c->x86_num_cores & (c->x86_num_cores - 1)) + c->x86_num_cores = 1; + } + + detect_ht(c); #ifdef CONFIG_X86_HT /* AMD dual core looks like HT but isn't really. Hide it from the @@ -203,13 +210,8 @@ static void __init init_amd(struct cpuin TBD tune the domain scheduler for dual core. */ if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) smp_num_siblings = 1; -#endif - if (cpuid_eax(0x80000000) >= 0x80000008) { - c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; - if (c->x86_num_cores & (c->x86_num_cores - 1)) - c->x86_num_cores = 1; - } +#endif } static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/arch/x86/cpu/intel.c xeno.0611/xen/arch/x86/cpu/intel.c --- xeno-today/xen/arch/x86/cpu/intel.c 2005-05-28 12:19:58.000000000 -0500 +++ xeno.0611/xen/arch/x86/cpu/intel.c 2005-06-19 04:11:04.000000000 -0500 @@ -73,6 +73,26 @@ static void __init Intel_errata_workarou } } +/* + * find out the number of processor cores on the die + */ +static int __init num_cpu_cores(struct cpuinfo_x86 *c) +{ + unsigned int eax; + + if (c->cpuid_level < 4) + return 1; + + __asm__("cpuid" + : "=a" (eax) + : "0" (4), "c" (0) + : "bx", "dx"); + + if (eax & 0x1f) + return ((eax >> 26) + 1); + else + return 1; +} static void __init init_intel(struct cpuinfo_x86 *c) { @@ -136,6 +156,8 @@ static void __init init_intel(struct cpu if ( p ) strcpy(c->x86_model_id, p); + c->x86_num_cores = num_cpu_cores(c); + detect_ht(c); /* Work around errata */ diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/arch/x86/dom0_ops.c xeno.0611/xen/arch/x86/dom0_ops.c --- xeno-today/xen/arch/x86/dom0_ops.c 2005-06-09 20:22:20.000000000 -0500 +++ xeno.0611/xen/arch/x86/dom0_ops.c 2005-06-19 13:09:33.000000000 -0500 @@ -179,8 +179,8 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 { dom0_physinfo_t *pi = &op->u.physinfo; - pi->ht_per_core = ht_per_core; - pi->cores = num_online_cpus() / ht_per_core; + pi->ht_per_core = smp_num_siblings; + pi->cores = boot_cpu_data.x86_num_cores; pi->total_pages = max_page; pi->free_pages = avail_domheap_pages(); pi->cpu_khz = cpu_khz; diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/arch/x86/setup.c xeno.0611/xen/arch/x86/setup.c --- xeno-today/xen/arch/x86/setup.c 2005-06-09 20:22:20.000000000 -0500 +++ xeno.0611/xen/arch/x86/setup.c 2005-06-19 13:00:53.000000000 -0500 @@ -66,7 +66,6 @@ boolean_param("noapic", skip_ioapic_setu int early_boot = 1; -int ht_per_core = 1; cpumask_t cpu_present_map; /* Limits of Xen heap, used to initialise the allocator. */ diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/arch/x86/smpboot.c xeno.0611/xen/arch/x86/smpboot.c --- xeno-today/xen/arch/x86/smpboot.c 2005-06-09 20:22:20.000000000 -0500 +++ xeno.0611/xen/arch/x86/smpboot.c 2005-06-20 11:05:45.000000000 -0500 @@ -63,6 +63,9 @@ int smp_num_siblings = 1; int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ EXPORT_SYMBOL(phys_proc_id); +int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ +EXPORT_SYMBOL(cpu_core_id); + /* bitmap of online cpus */ cpumask_t cpu_online_map; @@ -923,6 +926,8 @@ static int boot_cpu_logical_apicid; void *xquad_portio; cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; +cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; +EXPORT_SYMBOL(cpu_core_map); static void __init smp_boot_cpus(unsigned int max_cpus) { @@ -947,6 +952,9 @@ static void __init smp_boot_cpus(unsigne cpus_clear(cpu_sibling_map[0]); cpu_set(0, cpu_sibling_map[0]); + cpus_clear(cpu_core_map[0]); + cpu_set(0, cpu_core_map[0]); + /* * If we couldn't find an SMP configuration at boot time, * get out of here now! @@ -959,6 +967,8 @@ static void __init smp_boot_cpus(unsigne printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); map_cpu_to_logical_apicid(); + cpu_set(0, cpu_sibling_map[0]); + cpu_set(0, cpu_core_map[0]); return; } @@ -979,6 +989,7 @@ static void __init smp_boot_cpus(unsigne 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); + printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); goto init_uniprocessor; } @@ -987,8 +998,10 @@ static void __init smp_boot_cpus(unsigne /* * If SMP should be disabled, then really disable it! */ - if (!max_cpus) + if (!max_cpus) { + smp_found_config = 0; goto init_uniprocessor; + } connect_bsp_APIC(); setup_local_APIC(); @@ -1079,20 +1092,24 @@ static void __init smp_boot_cpus(unsigne * construct cpu_sibling_map[], so that we can tell sibling CPUs * efficiently. */ - for (cpu = 0; cpu < NR_CPUS; cpu++) + for (cpu = 0; cpu < NR_CPUS; cpu++) { cpus_clear(cpu_sibling_map[cpu]); + cpus_clear(cpu_core_map[cpu]); + } for (cpu = 0; cpu < NR_CPUS; cpu++) { + struct cpuinfo_x86 *c = cpu_data + 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 (!cpu_isset(i, cpu_callout_map)) continue; - if (phys_proc_id[cpu] == phys_proc_id[i]) { + if (cpu_core_id[cpu] == cpu_core_id[i]) { siblings++; cpu_set(i, cpu_sibling_map[cpu]); } @@ -1102,10 +1119,26 @@ static void __init smp_boot_cpus(unsigne cpu_set(cpu, cpu_sibling_map[cpu]); } - if (siblings != smp_num_siblings) + + 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; + } + + if (c->x86_num_cores > 1) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_isset(i, cpu_callout_map)) + continue; + if (phys_proc_id[cpu] == phys_proc_id[i]) { + cpu_set(i, cpu_core_map[cpu]); + } + } + } else { + cpu_core_map[cpu] = cpu_sibling_map[cpu]; + } } + if (nmi_watchdog == NMI_LOCAL_APIC) check_nmi_watchdog(); diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/common/dom0_ops.c xeno.0611/xen/common/dom0_ops.c --- xeno-today/xen/common/dom0_ops.c 2005-06-09 20:22:21.000000000 -0500 +++ xeno.0611/xen/common/dom0_ops.c 2005-06-19 13:21:11.000000000 -0500 @@ -184,8 +184,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op) * domains will all share the second HT of each CPU. Since dom0 is on * CPU 0, we favour high numbered CPUs in the event of a tie. */ - pro = ht_per_core - 1; - for ( i = pro; i < num_online_cpus(); i += ht_per_core ) + pro = smp_num_siblings - 1; + for ( i = pro; i < num_online_cpus(); i += smp_num_siblings) if ( cnt[i] <= cnt[pro] ) pro = i; diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/include/asm-x86/processor.h xeno.0611/xen/include/asm-x86/processor.h --- xeno-today/xen/include/asm-x86/processor.h 2005-06-06 11:54:29.000000000 -0500 +++ xeno.0611/xen/include/asm-x86/processor.h 2005-06-19 12:21:17.000000000 -0500 @@ -181,6 +181,7 @@ extern struct cpuinfo_x86 cpu_data[]; #endif extern int phys_proc_id[NR_CPUS]; +extern int cpu_core_id[NR_CPUS]; extern void identify_cpu(struct cpuinfo_x86 *); extern void print_cpu_info(struct cpuinfo_x86 *); diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/include/asm-x86/smp.h xeno.0611/xen/include/asm-x86/smp.h --- xeno-today/xen/include/asm-x86/smp.h 2005-06-06 11:54:29.000000000 -0500 +++ xeno.0611/xen/include/asm-x86/smp.h 2005-06-20 11:05:43.000000000 -0500 @@ -34,6 +34,7 @@ extern void smp_alloc_memory(void); extern int pic_mode; extern int smp_num_siblings; extern cpumask_t cpu_sibling_map[]; +extern cpumask_t cpu_core_map[]; extern void smp_flush_tlb(void); extern void smp_invalidate_rcv(void); /* Process an NMI */ diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/include/xen/smp.h xeno.0611/xen/include/xen/smp.h --- xeno-today/xen/include/xen/smp.h 2005-06-09 20:22:21.000000000 -0500 +++ xeno.0611/xen/include/xen/smp.h 2005-06-19 13:21:11.000000000 -0500 @@ -58,8 +58,6 @@ static inline int on_each_cpu(void (*fun return ret; } -extern int ht_per_core; - extern volatile unsigned long smp_msg_data; extern volatile int smp_src_cpu; extern volatile int smp_msg_id; diff -Nurp -X dontdiff -X dontdiff.xen xeno-today/xen/arch/x86/cpu/common.c xeno.0611/xen/arch/x86/cpu/common.c --- xeno-today/xen/arch/x86/cpu/common.c 2005-06-06 11:54:29.000000000 -0500 +++ xeno.0611/xen/arch/x86/cpu/common.c 2005-06-20 11:45:05.117949648 -0500 @@ -431,7 +431,7 @@ void __init dodgy_tsc(void) void __init detect_ht(struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx; - int index_lsb, index_msb, tmp; + int index_msb, tmp; int cpu = smp_processor_id(); if (!cpu_has(c, X86_FEATURE_HT)) @@ -443,7 +443,6 @@ void __init detect_ht(struct cpuinfo_x86 if (smp_num_siblings == 1) { printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); } else if (smp_num_siblings > 1 ) { - index_lsb = 0; index_msb = 31; if (smp_num_siblings > NR_CPUS) { @@ -452,21 +451,34 @@ void __init detect_ht(struct cpuinfo_x86 return; } tmp = smp_num_siblings; - while ((tmp & 1) == 0) { - tmp >>=1 ; - index_lsb++; - } - tmp = smp_num_siblings; while ((tmp & 0x80000000 ) == 0) { tmp <<=1 ; index_msb--; } - if (index_lsb != index_msb ) + if (smp_num_siblings & (smp_num_siblings - 1)) index_msb++; phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); printk(KERN_INFO "CPU: Physical Processor ID: %d\n", phys_proc_id[cpu]); + + smp_num_siblings = smp_num_siblings / c->x86_num_cores; + + tmp = smp_num_siblings; + index_msb = 31; + while ((tmp & 0x80000000) == 0) { + tmp <<=1 ; + index_msb--; + } + + if (smp_num_siblings & (smp_num_siblings - 1)) + index_msb++; + + cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); + + if (c->x86_num_cores > 1) + printk(KERN_INFO "CPU: Processor Core ID: %d\n", + cpu_core_id[cpu]); } } #endif