Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4594

kernel-2.6.18-194.11.1.el5.src.rpm

From: Bhavana Nagendra <bnagendr@redhat.com>
Date: Wed, 26 Mar 2008 13:51:23 -0400
Subject: [xen] x86: new vcpu_op call to get physical CPU identity
Message-id: 47EA8D1B.9090706@redhat.com
O-Subject: Re: [RHEL5.2 PATCH 2/2] Xen HV: New vcpu_op call to get physical CPU identity.
Bugzilla: 434548
RH-Acked-by: Stephen C. Tweedie <sct@redhat.com>
RH-Acked-by: Rik van Riel <riel@redhat.com>

With this patch we have the following fixes:
1) Removed global reference to "opt_dom0_vcpus_pin" in schedule.c.  This
was a mistake.
2) The "opt_dom0_vcpus_pin" definition is global now to match the
version removed from schedule.c.
The upstream version is static, which is why my back port originally
defined it as static.   I agree that it's
better to match the RHEL specific version.
3) Retained the "opt_dom0_vcpus_pin" in domain_build() as Rik added this
in his cpufreq and  Power
Now! in Xen back port.   Stephen is following up separately.

The "opt_dom0_vcpus_pin" moved from schedule.c to domain.c due to a
dependency, it wasn't an idle
move.  Also matches upstream in that regard, with some RHEL specific
changes noted above.

Bhavana

diff --git a/arch/x86/acpi/boot.c b/arch/x86/acpi/boot.c
index 76f329d..3b76219 100644
--- a/arch/x86/acpi/boot.c
+++ b/arch/x86/acpi/boot.c
@@ -920,3 +920,17 @@ int __init acpi_boot_init(void)
 
 	return 0;
 }
+
+unsigned int acpi_get_processor_id(unsigned int cpu)
+{
+	unsigned int acpiid, apicid;
+
+	if ((apicid = x86_cpu_to_apicid[cpu]) == 0xff)
+		return 0xff;
+
+	for (acpiid = 0; acpiid < ARRAY_SIZE(x86_acpiid_to_apicid); acpiid++)
+		if (x86_acpiid_to_apicid[acpiid] == apicid)
+			return acpiid;
+
+	return 0xff;
+}
diff --git a/arch/x86/domain.c b/arch/x86/domain.c
index 9ff936e..db86d09 100644
--- a/arch/x86/domain.c
+++ b/arch/x86/domain.c
@@ -29,6 +29,7 @@
 #include <xen/console.h>
 #include <xen/percpu.h>
 #include <xen/compat.h>
+#include <xen/acpi.h>
 #include <asm/regs.h>
 #include <asm/mc146818rtc.h>
 #include <asm/system.h>
@@ -891,6 +892,25 @@ arch_do_vcpu_op(
         break;
     }
 
+    case VCPUOP_get_physid:
+    {
+        struct vcpu_get_physid cpu_id;
+
+        rc = -EINVAL;
+        if ( !v->domain->is_pinned )
+            break;
+
+        cpu_id.phys_id = (x86_cpu_to_apicid[v->vcpu_id] |
+                          (acpi_get_processor_id(v->vcpu_id) << 8));
+
+        rc = -EFAULT;
+        if ( copy_to_guest(arg, &cpu_id, 1) )
+            break;
+
+        rc = 0;
+        break;
+    }
+
     default:
         rc = -ENOSYS;
         break;
diff --git a/common/domain.c b/common/domain.c
index fa7a2e3..0984cf8 100644
--- a/common/domain.c
+++ b/common/domain.c
@@ -30,6 +30,24 @@
 #include <public/vcpu.h>
 #include <acm/acm_hooks.h>
 
+/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
+unsigned int opt_dom0_vcpus_pin = 1;
+boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
+
+enum cpufreq_controller cpufreq_controller = FREQCTL_dom0_kernel;
+static void __init setup_cpufreq_option(char *str)
+{
+    if ( !strcmp(str, "dom0-kernel") )
+    {
+        cpufreq_controller = FREQCTL_dom0_kernel;
+        opt_dom0_vcpus_pin = 1;
+    } else if ( !strcmp(str, "off") || !strcmp(str, "none") ) {
+        cpufreq_controller = FREQCTL_none;
+        opt_dom0_vcpus_pin = 0;
+    }
+}
+custom_param("cpufreq", setup_cpufreq_option);
+
 /* Protect updates/reads (resp.) of domain_list and domain_hash. */
 DEFINE_SPINLOCK(domlist_update_lock);
 DEFINE_RCU_READ_LOCK(domlist_read_lock);
@@ -189,6 +207,9 @@ struct domain *domain_create(
     if ( domcr_flags & DOMCRF_hvm )
         d->is_hvm = 1;
 
+    if ( (domid == 0) && opt_dom0_vcpus_pin )
+        d->is_pinned = 1;
+
     rangeset_domain_initialise(d);
 
     if ( !is_idle_domain(d) )
diff --git a/common/schedule.c b/common/schedule.c
index b27771c..cdb9887 100644
--- a/common/schedule.c
+++ b/common/schedule.c
@@ -37,24 +37,6 @@
 static char opt_sched[10] = "credit";
 string_param("sched", opt_sched);
 
-/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
-unsigned int opt_dom0_vcpus_pin = 1;
-boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
-
-enum cpufreq_controller cpufreq_controller = FREQCTL_dom0_kernel;
-static void __init setup_cpufreq_option(char *str)
-{
-    if ( !strcmp(str, "dom0-kernel") )
-    {
-        cpufreq_controller = FREQCTL_dom0_kernel;
-        opt_dom0_vcpus_pin = 1;
-    } else if ( !strcmp(str, "off") || !strcmp(str, "none") ) {
-        cpufreq_controller = FREQCTL_none;
-        opt_dom0_vcpus_pin = 0;
-    }
-}
-custom_param("cpufreq", setup_cpufreq_option);
-
 #define TIME_SLOP      (s32)MICROSECS(50)     /* allow time to slip a bit */
 
 /* Various timer handlers. */
@@ -119,7 +101,7 @@ int sched_init_vcpu(struct vcpu *v, unsigned int processor)
      * domain-0 VCPUs, are pinned onto their respective physical CPUs.
      */
     v->processor = processor;
-    if ( is_idle_domain(d) || ((d->domain_id == 0) && opt_dom0_vcpus_pin) )
+    if ( is_idle_domain(d) || d->is_pinned )
         v->cpu_affinity = cpumask_of_cpu(processor);
     else
         cpus_setall(v->cpu_affinity);
@@ -304,7 +286,7 @@ static int __vcpu_set_affinity(
 
 int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity)
 {
-    if ( (v->domain->domain_id == 0) && opt_dom0_vcpus_pin )
+    if ( v->domain->is_pinned )
         return -EINVAL;
     return __vcpu_set_affinity(v, affinity, 0, 0);
 }
diff --git a/include/public/vcpu.h b/include/public/vcpu.h
index a84eb51..81e425e 100644
--- a/include/public/vcpu.h
+++ b/include/public/vcpu.h
@@ -170,7 +170,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_set_singleshot_timer_t);
  *
  * This may be called only once per vcpu.
  */
-#define VCPUOP_register_vcpu_info   10  /* arg == struct vcpu_info */
+#define VCPUOP_register_vcpu_info   10  /* arg == vcpu_register_vcpu_info_t */
 struct vcpu_register_vcpu_info {
     uint64_t mfn;    /* mfn of page to place vcpu_info */
     uint32_t offset; /* offset within page */
@@ -179,6 +179,22 @@ struct vcpu_register_vcpu_info {
 typedef struct vcpu_register_vcpu_info vcpu_register_vcpu_info_t;
 DEFINE_XEN_GUEST_HANDLE(vcpu_register_vcpu_info_t);
 
+/* 
+ * Get the physical ID information for a pinned vcpu's underlying physical
+ * processor.  The physical ID informmation is architecture-specific.
+ * On x86: id[7:0]=apic_id, id[15:8]=acpi_id, id[63:16]=mbz,
+ *         and an unavailable identifier is returned as 0xff.
+ * This command returns -EINVAL if it is not a valid operation for this VCPU.
+ */
+#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);
+#define xen_vcpu_physid_to_x86_apicid(physid) ((uint8_t)((physid)>>0))
+#define xen_vcpu_physid_to_x86_acpiid(physid) ((uint8_t)((physid)>>8))
+
 #endif /* __XEN_PUBLIC_VCPU_H__ */
 
 /*
diff --git a/include/xen/acpi.h b/include/xen/acpi.h
index aa7a36a..4df2fcb 100644
--- a/include/xen/acpi.h
+++ b/include/xen/acpi.h
@@ -376,6 +376,7 @@ extern acpi_table_handler acpi_table_ops[ACPI_TABLE_COUNT];
 
 typedef int (*acpi_madt_entry_handler) (acpi_table_entry_header *header, const unsigned long end);
 
+unsigned int acpi_get_processor_id (unsigned int cpu);
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 unsigned long acpi_find_rsdp (void);
 int acpi_boot_init (void);
diff --git a/include/xen/sched.h b/include/xen/sched.h
index ec6afa1..2c3fefb 100644
--- a/include/xen/sched.h
+++ b/include/xen/sched.h
@@ -196,6 +196,8 @@ struct domain
     enum { DOMDYING_alive, DOMDYING_dying, DOMDYING_dead } is_dying;
     /* Domain is paused by controller software? */
     bool_t           is_paused_by_controller;
+    /* Domain's VCPUs are pinned 1:1 to physical CPUs? */
+    bool_t           is_pinned;
 
     /* Guest has shut down (inc. reason code)? */
     spinlock_t       shutdown_lock;