diff options
author | Wei Huang <wei.huang2@amd.com> | 2011-06-28 09:13:53 +0100 |
---|---|---|
committer | Wei Huang <wei.huang2@amd.com> | 2011-06-28 09:13:53 +0100 |
commit | 9a75615782f763326e1ad2a2aad4e8c9966755e3 (patch) | |
tree | 60cc8c13f41fce864b07e4d3a9efe989981f5662 /xen/arch/x86/smpboot.c | |
parent | 5f84766a30c8911e4f39c4b7dbdd01394e1d5224 (diff) | |
download | xen-9a75615782f763326e1ad2a2aad4e8c9966755e3.tar.gz xen-9a75615782f763326e1ad2a2aad4e8c9966755e3.tar.bz2 xen-9a75615782f763326e1ad2a2aad4e8c9966755e3.zip |
x86: AMD core-pair topology detection code
This patch is to support core-pair topology introduced by AMD CPUs,
which introduces a new concept of [core, compute unit]. There is a new
feature bit for topology extension in CPUID:0x80000001. Also a new
CPUID 0x8000001E is introduced for CPU topology enumeration. This
patch collects the sibling information from the new CPUID and will be
stored in the sibling map in Xen hypervisor.
Signed-off-by: Wei Huang <wei.huang2@amd.com>
Diffstat (limited to 'xen/arch/x86/smpboot.c')
-rw-r--r-- | xen/arch/x86/smpboot.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 6f48a40443..ccf1c0e5ca 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -230,6 +230,14 @@ static int booting_cpu; /* CPUs for which sibling maps can be computed. */ static cpumask_t cpu_sibling_setup_map; +static void link_thread_siblings(int cpu1, int cpu2) +{ + cpu_set(cpu1, per_cpu(cpu_sibling_map, cpu2)); + cpu_set(cpu2, per_cpu(cpu_sibling_map, cpu1)); + cpu_set(cpu1, per_cpu(cpu_core_map, cpu2)); + cpu_set(cpu2, per_cpu(cpu_core_map, cpu1)); +} + static void set_cpu_sibling_map(int cpu) { int i; @@ -241,13 +249,13 @@ static void set_cpu_sibling_map(int cpu) { for_each_cpu_mask ( i, cpu_sibling_setup_map ) { - if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) && - (c[cpu].cpu_core_id == c[i].cpu_core_id) ) - { - cpu_set(i, per_cpu(cpu_sibling_map, cpu)); - cpu_set(cpu, per_cpu(cpu_sibling_map, i)); - cpu_set(i, per_cpu(cpu_core_map, cpu)); - cpu_set(cpu, per_cpu(cpu_core_map, i)); + if ( cpu_has(c, X86_FEATURE_TOPOEXT) ) { + if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) && + (c[cpu].compute_unit_id == c[i].compute_unit_id) ) + link_thread_siblings(cpu, i); + } else if ( (c[cpu].phys_proc_id == c[i].phys_proc_id) && + (c[cpu].cpu_core_id == c[i].cpu_core_id) ) { + link_thread_siblings(cpu, i); } } } @@ -828,6 +836,7 @@ remove_siblinginfo(int cpu) cpus_clear(per_cpu(cpu_core_map, cpu)); c[cpu].phys_proc_id = BAD_APICID; c[cpu].cpu_core_id = BAD_APICID; + c[cpu].compute_unit_id = BAD_APICID; cpu_clear(cpu, cpu_sibling_setup_map); } |