800917b5a2
- Update to Xen 4.1.2_rc2 c/s 23152 - bnc#716695 - domUs using tap devices will not start updated multi-xvdp.patch - Upstream patches from Jan 23803-intel-pmu-models.patch 23800-x86_64-guest-addr-range.patch 23795-intel-ich10-quirk.patch 23804-x86-IPI-counts.patch - bnc#706106 - Inconsistent reporting of VM names during migration xend-migration-domname-fix.patch - bnc#712823 - L3:Xen guest does not start reliable when rebooted xend-vcpu-affinity-fix.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=143
177 lines
6.4 KiB
Diff
177 lines
6.4 KiB
Diff
References: fate#309894
|
|
|
|
# HG changeset patch
|
|
# User Wei Huang <wei.huang2@amd.com>
|
|
# Date 1309248833 -3600
|
|
# Node ID c2c12b2dafb5b1d3bfcc4c05a60ca4f9051c90e7
|
|
# Parent 87c2013c2aa2d4874f892507e6cc7b52219a3acf
|
|
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>
|
|
|
|
Index: xen-4.1.2-testing/xen/arch/x86/cpu/amd.c
|
|
===================================================================
|
|
--- xen-4.1.2-testing.orig/xen/arch/x86/cpu/amd.c
|
|
+++ xen-4.1.2-testing/xen/arch/x86/cpu/amd.c
|
|
@@ -344,6 +344,49 @@ static void check_syscfg_dram_mod_en(voi
|
|
wrmsrl(MSR_K8_SYSCFG, syscfg);
|
|
}
|
|
|
|
+static void __devinit amd_get_topology(struct cpuinfo_x86 *c)
|
|
+{
|
|
+#ifdef CONFIG_X86_HT
|
|
+ int cpu;
|
|
+ unsigned bits;
|
|
+
|
|
+ if (c->x86_max_cores <= 1)
|
|
+ return;
|
|
+ /*
|
|
+ * On a AMD multi core setup the lower bits of the APIC id
|
|
+ * distingush the cores.
|
|
+ */
|
|
+ cpu = smp_processor_id();
|
|
+ bits = (cpuid_ecx(0x80000008) >> 12) & 0xf;
|
|
+
|
|
+ if (bits == 0) {
|
|
+ while ((1 << bits) < c->x86_max_cores)
|
|
+ bits++;
|
|
+ }
|
|
+
|
|
+ /* Low order bits define the core id */
|
|
+ c->cpu_core_id = c->phys_proc_id & ((1<<bits)-1);
|
|
+ /* Convert local APIC ID into the socket ID */
|
|
+ c->phys_proc_id >>= bits;
|
|
+ /* Collect compute unit ID if available */
|
|
+ if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
|
|
+ u32 eax, ebx, ecx, edx;
|
|
+
|
|
+ cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
|
|
+ c->compute_unit_id = ebx & 0xFF;
|
|
+ c->x86_num_siblings = ((ebx >> 8) & 0x3) + 1;
|
|
+ }
|
|
+
|
|
+ if (opt_cpu_info)
|
|
+ printk("CPU %d(%d) -> Processor %d, %s %d\n",
|
|
+ cpu, c->x86_max_cores, c->phys_proc_id,
|
|
+ cpu_has(c, X86_FEATURE_TOPOEXT) ? "Compute Unit" :
|
|
+ "Core",
|
|
+ cpu_has(c, X86_FEATURE_TOPOEXT) ? c->compute_unit_id :
|
|
+ c->cpu_core_id);
|
|
+#endif
|
|
+}
|
|
+
|
|
static void __devinit init_amd(struct cpuinfo_x86 *c)
|
|
{
|
|
u32 l, h;
|
|
@@ -566,26 +609,7 @@ static void __devinit init_amd(struct cp
|
|
}
|
|
}
|
|
|
|
-#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++;
|
|
- }
|
|
- c->cpu_core_id = c->phys_proc_id & ((1<<bits)-1);
|
|
- c->phys_proc_id >>= bits;
|
|
- if (opt_cpu_info)
|
|
- printk("CPU %d(%d) -> Core %d\n",
|
|
- cpu, c->x86_max_cores, c->cpu_core_id);
|
|
- }
|
|
-#endif
|
|
+ amd_get_topology(c);
|
|
|
|
/* Pointless to use MWAIT on Family10 as it does not deep sleep. */
|
|
if (c->x86 >= 0x10 && !force_mwait)
|
|
Index: xen-4.1.2-testing/xen/arch/x86/cpu/common.c
|
|
===================================================================
|
|
--- xen-4.1.2-testing.orig/xen/arch/x86/cpu/common.c
|
|
+++ xen-4.1.2-testing/xen/arch/x86/cpu/common.c
|
|
@@ -364,6 +364,7 @@ void __cpuinit identify_cpu(struct cpuin
|
|
c->x86_clflush_size = 0;
|
|
c->phys_proc_id = BAD_APICID;
|
|
c->cpu_core_id = BAD_APICID;
|
|
+ c->compute_unit_id = BAD_APICID;
|
|
memset(&c->x86_capability, 0, sizeof c->x86_capability);
|
|
|
|
if (!have_cpuid_p()) {
|
|
Index: xen-4.1.2-testing/xen/arch/x86/smpboot.c
|
|
===================================================================
|
|
--- xen-4.1.2-testing.orig/xen/arch/x86/smpboot.c
|
|
+++ xen-4.1.2-testing/xen/arch/x86/smpboot.c
|
|
@@ -240,6 +240,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;
|
|
@@ -251,13 +259,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);
|
|
}
|
|
}
|
|
}
|
|
@@ -838,6 +846,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);
|
|
}
|
|
|
|
Index: xen-4.1.2-testing/xen/include/asm-x86/processor.h
|
|
===================================================================
|
|
--- xen-4.1.2-testing.orig/xen/include/asm-x86/processor.h
|
|
+++ xen-4.1.2-testing/xen/include/asm-x86/processor.h
|
|
@@ -175,9 +175,10 @@ struct cpuinfo_x86 {
|
|
__u32 x86_max_cores; /* cpuid returned max cores value */
|
|
__u32 booted_cores; /* number of cores as seen by OS */
|
|
__u32 x86_num_siblings; /* cpuid logical cpus per chip value */
|
|
+ __u32 apicid;
|
|
int phys_proc_id; /* package ID of each logical CPU */
|
|
int cpu_core_id; /* core ID of each logical CPU*/
|
|
- __u32 apicid;
|
|
+ int compute_unit_id; /* AMD compute unit ID of each logical CPU */
|
|
unsigned short x86_clflush_size;
|
|
} __cacheline_aligned;
|
|
|