Skip to contentSkip to conversation

new vcpu op call to get physical CPU information

PATCH In review Mark Langsdorf 4 participants 5 messages Mar 4, 2008 – Mar 5, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 new vcpu op call to get physical CPU information

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).

Add a vcpu op to Xen to allow dom0 to query the hypervisor for architecture dependent physical cpu information if dom0 vcpus are pinned.

The second patch adds the dom0 call to this vcpu hypercall.

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

xen/arch/x86/domain.c +24 -0
diff -r 7530c4dba8a5 xen/arch/x86/domain.c
@@ -952,6 +952,30 @@ arch_do_vcpu_op(
         break;
     }
 
+    case VCPUOP_get_physid:
+    {
+        struct vcpu_get_physid cpu_id;
+        int i;
+        int cpu_num = v->vcpu_id;
+	short temp = 0xff;
+
+        if ( !opt_dom0_vcpus_pin)
+            rc = -EINVAL;
+        rc = -EFAULT;
+
+        cpu_id.phys_id = x86_cpu_to_apicid[cpu_num];
+        for (i = 0; i++; i < NR_CPUS) 
+             if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu_num])
+                 temp = i;
+	cpu_id.phys_id |= temp << 8;
+
+        if ( copy_to_guest(arg, &cpu_id, 1) )
+            break;
+        rc = 0;
+
+        break;
+    }
+
     default:
         rc = -ENOSYS;
         break;
xen/common/schedule.c +2 -1
diff -r 7530c4dba8a5 xen/common/schedule.c
@@ -39,7 +39,8 @@ string_param("sched", opt_sched);
 string_param("sched", opt_sched);
 
 /* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
-static unsigned int opt_dom0_vcpus_pin;
+unsigned int opt_dom0_vcpus_pin;
+EXPORT_SYMBOL(opt_dom0_vcpus_pin);
 boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
 
 enum cpufreq_controller cpufreq_controller;
xen/include/public/vcpu.h +11 -0
diff -r 7530c4dba8a5 xen/include/public/vcpu.h
@@ -182,6 +182,17 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_register_vc
 /* Send an NMI to the specified VCPU. @extra_arg == NULL. */
 #define VCPUOP_send_nmi             11
 
+/* 
+ * Get the physical ID information for a pinned vcpu's underlying
+ * physical processor.  The phyiscal ID informmation is architecture
+ * defined, but would ACPI and APIC IDs on x86 processors.
+ */
+#define VCPUOP_get_physid           12 /* arg == vcpu_get_physid_t */
+struct vcpu_get_physid {
+    uint64_t phys_id;
+};
+typedef struct vcpu_get_physid vcpu_get_physid_t;
+DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_t);
 #endif /* __XEN_PUBLIC_VCPU_H__ */
 
 /*
xen/include/xen/sched.h +3 -0
diff -r 7530c4dba8a5 xen/include/xen/sched.h
@@ -29,6 +29,9 @@ extern unsigned long volatile jiffies;
 
 /* A global pointer to the initial domain (DOM0). */
 extern struct domain *dom0;
+
+/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
+extern unsigned int opt_dom0_vcpus_pin;
 
 #ifndef CONFIG_COMPAT
 #define MAX_EVTCHNS(d)     NR_EVENT_CHANNELS
#1 lore raw

Re: [PATCH][retry 3][1/2] new vcpu op call to get physicalCPU information

xen/arch/x86/domain.c arch_do_vcpu_op( · line 960

Quoted 1 line
xen/arch/x86/domain.c +1 -0
+	short temp = 0xff;

Please use 0xffffffff here for forward compatibility.

xen/arch/x86/domain.c arch_do_vcpu_op( · line 964

Quoted 4 lines
xen/arch/x86/domain.c +4 -0
+
+        if ( !opt_dom0_vcpus_pin)
+            rc = -EINVAL;
+        rc = -EFAULT;

This makes no sense; it's probably missing a 'break'.

xen/arch/x86/domain.c arch_do_vcpu_op( · line 970

Quoted 6 lines
xen/arch/x86/domain.c +6 -0
+
+        cpu_id.phys_id = x86_cpu_to_apicid[cpu_num];
+        for (i = 0; i++; i < NR_CPUS) 
+             if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu_num])
+                 temp = i;
+	cpu_id.phys_id |= temp << 8;

Please shift by 32 here for forward compatibility.

xen/common/schedule.c string_param("sched", opt_sched); · line 43

Quoted 3 lines
xen/common/schedule.c +2 -1
-static unsigned int opt_dom0_vcpus_pin;
+unsigned int opt_dom0_vcpus_pin;
+EXPORT_SYMBOL(opt_dom0_vcpus_pin);

EXPORT_SYMBOL()?

Jan

#2 lore raw

Re: [PATCH][retry 3][1/2] new vcpu op call to get physicalCPU information

Jan Beulich writes ("Re: [Xen-devel] [PATCH][retry 3][1/2] new vcpu op call to get physicalCPU information"):

Quoted 1 line
Quoted 1 line
xen/arch/x86/domain.c +1 -0
+	short temp = 0xff;

...

Quoted 3 lines

xen/arch/x86/domain.c arch_do_vcpu_op( · line 970

Quoted 1 line
xen/arch/x86/domain.c +1 -0
+	cpu_id.phys_id |= temp << 8;

Please shift by 32 here for forward compatibility.

short promotes to int, probably 32-bit, but shifting by the word size or more is not permitted. In any case even if it worked like you wanted, the result would be 0. Perhaps you meant to suggest some changes of types as well ?

Ian.

#3 lore raw

Re: [PATCH][retry 3][1/2] new vcpu op call to getphysicalCPU information

Quoted 4 lines
Quoted 1 line
Quoted 1 line

Ian Jackson <[email protected]> 05.03.08 12:40 >>>

Jan Beulich writes ("Re: [Xen-devel] [PATCH][retry 3][1/2] new vcpu op call to get physicalCPU information"):

Quoted 1 line
Quoted 1 line
xen/arch/x86/domain.c +1 -0
+	short temp = 0xff;

...

Quoted 8 lines
Quoted 3 lines

xen/arch/x86/domain.c arch_do_vcpu_op( · line 970

Quoted 1 line
xen/arch/x86/domain.c +1 -0
+	cpu_id.phys_id |= temp << 8;

Please shift by 32 here for forward compatibility.

short promotes to int, probably 32-bit, but shifting by the word size or more is not permitted. In any case even if it worked like you wanted, the result would be 0. Perhaps you meant to suggest some changes of types as well ?

Of course.

Jan

#4 lore raw
In reply to Mark Langsdorf

xen/arch/x86/domain.c arch_do_vcpu_op( · line 969

Quoted 3 lines · Mark Langsdorf
xen/arch/x86/domain.c +3 -0
+        for (i = 0; i++; i < NR_CPUS)
+             if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu_num])
+                 temp = i;

A novel ordering for a for-loop header!

-- Keir