diff -r 94c5d7ee424a -r f8e36046ee17 xen/arch/x86/cpu/amd.c --- a/xen/arch/x86/cpu/amd.c Wed Jan 05 13:58:21 2011 -0600 +++ b/xen/arch/x86/cpu/amd.c Wed Jan 05 16:48:01 2011 -0600 @@ -337,6 +337,56 @@ on_each_cpu(disable_c1e, NULL, 1); } +#ifdef CONFIG_X86_HT +/* This function detects system CPU topology */ +static void amd_detect_topology(struct cpuinfo_x86 *c) +{ + u32 eax, ebx, ecx, edx; + int cpu = smp_processor_id(); + + if (c->x86_max_cores <= 1) + return; + + if (cpu_has(c, X86_FEATURE_TOPO_EXT)) { + /* AMD new CPUs introduce a new term called compute unit. But + * we still keep the names of existing variables for the + * purpose of consistency. Keep in mind that cpu_core_id here + * represents the computer unit ID; and we use the node ID as + * the processor ID because it is unique across the whole + * system. + */ + cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); + cpu_core_id[cpu] = ebx & 0xFF; + phys_proc_id[cpu] = ecx & 0xFF; + + c->x86_num_siblings = ((ebx >> 8) & 0x3) + 1; + + if (opt_cpu_info) + printk("CPU %d(%d) -> Compute Unit %d, Node %d\n", + cpu, c->x86_max_cores, cpu_core_id[cpu], + phys_proc_id[cpu]); + } else { + /* On a AMD multi core setup the lower bits of the APIC id + * distingush the cores. + */ + unsigned bits = (cpuid_ecx(0x80000008) >> 12) & 0xf; + + if (bits == 0) { + while ((1 << bits) < c->x86_max_cores) + bits++; + } + cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<>= bits; + + if (opt_cpu_info) + printk("CPU %d(%d) -> Core %d\n", + cpu, c->x86_max_cores, cpu_core_id[cpu]); + } +} +#else +#define amd_detect_topology(struct cpuinfo_x86 *c) (void(0)) +#endif + static void __devinit init_amd(struct cpuinfo_x86 *c) { u32 l, h; @@ -574,26 +624,7 @@ } } -#ifdef CONFIG_X86_HT - /* - * On a AMD multi core setup the lower bits of the APIC id - * distingush the cores. - */ - if (c->x86_max_cores > 1) { - int cpu = smp_processor_id(); - unsigned bits = (cpuid_ecx(0x80000008) >> 12) & 0xf; - - if (bits == 0) { - while ((1 << bits) < c->x86_max_cores) - bits++; - } - cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<>= bits; - if (opt_cpu_info) - printk("CPU %d(%d) -> Core %d\n", - cpu, c->x86_max_cores, cpu_core_id[cpu]); - } -#endif + amd_detect_topology(c); /* Pointless to use MWAIT on Family10 as it does not deep sleep. */ if (c->x86 >= 0x10 && !force_mwait) diff -r 94c5d7ee424a -r f8e36046ee17 xen/include/asm-x86/cpufeature.h --- a/xen/include/asm-x86/cpufeature.h Wed Jan 05 13:58:21 2011 -0600 +++ b/xen/include/asm-x86/cpufeature.h Wed Jan 05 16:48:01 2011 -0600 @@ -132,6 +132,7 @@ #define X86_FEATURE_SSE5 (6*32+ 11) /* AMD Streaming SIMD Extensions-5 */ #define X86_FEATURE_SKINIT (6*32+ 12) /* SKINIT, STGI/CLGI, DEV */ #define X86_FEATURE_WDT (6*32+ 13) /* Watchdog Timer */ +#define X86_FEATURE_TOPO_EXT (6*32+ 22) /* Topology Extension Support */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ #define X86_FEATURE_FSGSBASE (7*32+ 0) /* {RD,WR}{FS,GS}BASE instructions */