aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/smpboot.c
diff options
context:
space:
mode:
authorWei Huang <wei.huang2@amd.com>2011-06-28 09:13:53 +0100
committerWei Huang <wei.huang2@amd.com>2011-06-28 09:13:53 +0100
commit9a75615782f763326e1ad2a2aad4e8c9966755e3 (patch)
tree60cc8c13f41fce864b07e4d3a9efe989981f5662 /xen/arch/x86/smpboot.c
parent5f84766a30c8911e4f39c4b7dbdd01394e1d5224 (diff)
downloadxen-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.c23
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);
}