All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH][retry 2][2/2] new platform hypervisor call to get APICIDs
@ 2008-03-03 21:40 Mark Langsdorf
  2008-03-03 22:40 ` Chris Lalancette
  2008-03-04  8:59 ` Jan Beulich
  0 siblings, 2 replies; 7+ messages in thread
From: Mark Langsdorf @ 2008-03-03 21:40 UTC (permalink / raw)
  To: xen-devel, Chris Lalancette

Some AMD machines have APIC IDs that not equal to CPU IDs.  In
the default Xen configuration, ACPI calls on these machines
can get confused.  This shows up most noticeably when running
AMD PowerNow!.  The only solution is for dom0 to get the
hypervisor's cpuid to apicid table when needed (ie, when dom0
vcpus are pinned).

Make dom0 call a new platform hypercall that returns the
hypervisor's cpuid to apicid table.  The decision logic
(dom0_vcpus_pinned) is currently hard-coded but should be
passed from the hypervisor.  Keir wrote that he would take
care of that when he suggested this solution.

I have tested this on my 4p/16 core machine and it works.  I
would appreciate testing on other boxes.

-Mark Langsdorf
Operating System Research Center
AMD

Signed-off-by: Mark Langsdorf <mark.langsdorf@amd.com>

diff -r 1cf7ba68d855 drivers/xen/core/smpboot.c
--- a/drivers/xen/core/smpboot.c	Mon Mar 03 13:36:57 2008 +0000
+++ b/drivers/xen/core/smpboot.c	Mon Mar 03 14:40:26 2008 -0600
@@ -254,21 +254,39 @@ static void __cpuinit cpu_initialize_con
 	spin_unlock(&ctxt_lock);
 }
 
+int dom0_vcpus_pinned = 1;
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
 	unsigned int cpu;
 	struct task_struct *idle;
+	int apicid;
+	u8 pinned_apicids[NR_CPUS];
 #ifdef __x86_64__
 	struct desc_ptr *gdt_descr;
 #else
 	struct Xgt_desc_struct *gdt_descr;
 #endif
 
-	boot_cpu_data.apicid = 0;
+	if (dom0_vcpus_pinned) {
+		struct xen_platform_op op;
+		op.cmd = XENPF_getapicids;
+		set_xen_guest_handle(op.u.getapicids.apicids, pinned_apicids);
+		op.u.getapicids.nr_cpus = NR_CPUS;
+		if (HYPERVISOR_platform_op(&op)) {
+			/* failed to get valid data from hypervisor */
+			printk(KERN_ERR "failed to get valid APIC ID information\n");
+			dom0_vcpus_pinned = 0;
+			apicid = 0;
+		}
+		else
+			apicid = pinned_apicids[0];
+	} else
+		apicid = 0;
+	boot_cpu_data.apicid = apicid;
 	cpu_data[0] = boot_cpu_data;
 
-	cpu_2_logical_apicid[0] = 0;
-	x86_cpu_to_apicid[0] = 0;
+	cpu_2_logical_apicid[0] = apicid;
+	x86_cpu_to_apicid[0] = apicid;
 
 	current_thread_info()->cpu = 0;
 
@@ -312,11 +330,15 @@ void __init smp_prepare_cpus(unsigned in
 			(void *)gdt_descr->address,
 			XENFEAT_writable_descriptor_tables);
 
+		if (dom0_vcpus_pinned)
+			apicid = pinned_apicids[cpu];
+		else
+			apicid = cpu;
 		cpu_data[cpu] = boot_cpu_data;
-		cpu_data[cpu].apicid = cpu;
-
-		cpu_2_logical_apicid[cpu] = cpu;
-		x86_cpu_to_apicid[cpu] = cpu;
+		cpu_data[cpu].apicid = apicid;
+
+		cpu_2_logical_apicid[cpu] = apicid;
+		x86_cpu_to_apicid[cpu] = apicid;
 
 		idle = fork_idle(cpu);
 		if (IS_ERR(idle))
diff -r 1cf7ba68d855 include/xen/interface/platform.h
--- a/include/xen/interface/platform.h	Mon Mar 03 13:36:57 2008 +0000
+++ b/include/xen/interface/platform.h	Mon Mar 03 14:40:26 2008 -0600
@@ -198,6 +198,16 @@ struct xenpf_getidletime {
 };
 typedef struct xenpf_getidletime xenpf_getidletime_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
+
+#define XENPF_getapicids	54
+struct xenpf_getapicids {
+    /* IN variables */
+    /* size of apicid table */
+    uint32_t nr_cpus;
+    /* OUT variables */
+    /* Table of cpu to apicids */
+    XEN_GUEST_HANDLE(uint8) apicids;
+};
 
 struct xen_platform_op {
     uint32_t cmd;
@@ -213,6 +223,7 @@ struct xen_platform_op {
         struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
         struct xenpf_change_freq       change_freq;
         struct xenpf_getidletime       getidletime;
+	struct xenpf_getapicids	       getapicids;
         uint8_t                        pad[128];
     } u;
 };

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-03-04 18:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-03 21:40 [PATCH][retry 2][2/2] new platform hypervisor call to get APICIDs Mark Langsdorf
2008-03-03 22:40 ` Chris Lalancette
2008-03-04 17:57   ` Langsdorf, Mark
2008-03-04  8:59 ` Jan Beulich
2008-03-04  9:31   ` Keir Fraser
2008-03-04 11:43     ` Keir Fraser
2008-03-04 18:00       ` Langsdorf, Mark

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.