[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.2-testing] x86: New vcpu_op call to get physical CPU identity.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1204734177 0 # Node ID 6b805f7b65e50229bea9a53f561324c977b09912 # Parent 058acffbaa0c3c75551f0578d6b29f5c6fc5c102 x86: New vcpu_op call to get physical CPU identity. 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. Signed-off-by: Mark Langsdorf <mark.langsdorf@xxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> xen-unstable changeset: 17187:21532468020b2b09dba349b049fa81c0260f7a9f xen-unstable date: Wed Mar 05 10:52:51 2008 +0000 --- xen/arch/x86/acpi/boot.c | 14 ++++++++++++++ xen/arch/x86/domain.c | 20 ++++++++++++++++++++ xen/common/domain.c | 18 ++++++++++++++++++ xen/common/schedule.c | 19 ++----------------- xen/include/public/vcpu.h | 18 +++++++++++++++++- xen/include/xen/acpi.h | 1 + xen/include/xen/sched.h | 2 ++ 7 files changed, 74 insertions(+), 18 deletions(-) diff -r 058acffbaa0c -r 6b805f7b65e5 xen/arch/x86/acpi/boot.c --- a/xen/arch/x86/acpi/boot.c Wed Mar 05 16:22:23 2008 +0000 +++ b/xen/arch/x86/acpi/boot.c Wed Mar 05 16:22:57 2008 +0000 @@ -1028,3 +1028,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 -r 058acffbaa0c -r 6b805f7b65e5 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Mar 05 16:22:23 2008 +0000 +++ b/xen/arch/x86/domain.c Wed Mar 05 16:22:57 2008 +0000 @@ -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> @@ -945,6 +946,25 @@ arch_do_vcpu_op( rc = map_vcpu_info(v, info.mfn, info.offset); UNLOCK_BIGLOCK(d); + 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; } diff -r 058acffbaa0c -r 6b805f7b65e5 xen/common/domain.c --- a/xen/common/domain.c Wed Mar 05 16:22:23 2008 +0000 +++ b/xen/common/domain.c Wed Mar 05 16:22:57 2008 +0000 @@ -30,6 +30,21 @@ #include <public/vcpu.h> #include <xsm/xsm.h> +/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */ +static unsigned int opt_dom0_vcpus_pin; +boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin); + +enum cpufreq_controller cpufreq_controller; +static void __init setup_cpufreq_option(char *str) +{ + if ( !strcmp(str, "dom0-kernel") ) + { + cpufreq_controller = FREQCTL_dom0_kernel; + opt_dom0_vcpus_pin = 1; + } +} +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); @@ -197,6 +212,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); diff -r 058acffbaa0c -r 6b805f7b65e5 xen/common/schedule.c --- a/xen/common/schedule.c Wed Mar 05 16:22:23 2008 +0000 +++ b/xen/common/schedule.c Wed Mar 05 16:22:57 2008 +0000 @@ -38,21 +38,6 @@ static char opt_sched[10] = "credit"; static char opt_sched[10] = "credit"; string_param("sched", opt_sched); -/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */ -static unsigned int opt_dom0_vcpus_pin; -boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin); - -enum cpufreq_controller cpufreq_controller; -static void __init setup_cpufreq_option(char *str) -{ - if ( !strcmp(str, "dom0-kernel") ) - { - cpufreq_controller = FREQCTL_dom0_kernel; - opt_dom0_vcpus_pin = 1; - } -} -custom_param("cpufreq", setup_cpufreq_option); - #define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */ /* Various timer handlers. */ @@ -117,7 +102,7 @@ int sched_init_vcpu(struct vcpu *v, unsi * 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); @@ -302,7 +287,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 -r 058acffbaa0c -r 6b805f7b65e5 xen/include/public/vcpu.h --- a/xen/include/public/vcpu.h Wed Mar 05 16:22:23 2008 +0000 +++ b/xen/include/public/vcpu.h Wed Mar 05 16:22:57 2008 +0000 @@ -170,7 +170,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_set_singles * * 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 */ @@ -181,6 +181,22 @@ 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 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 -r 058acffbaa0c -r 6b805f7b65e5 xen/include/xen/acpi.h --- a/xen/include/xen/acpi.h Wed Mar 05 16:22:23 2008 +0000 +++ b/xen/include/xen/acpi.h Wed Mar 05 16:22:57 2008 +0000 @@ -446,6 +446,7 @@ extern acpi_table_handler acpi_table_ops 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 -r 058acffbaa0c -r 6b805f7b65e5 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Wed Mar 05 16:22:23 2008 +0000 +++ b/xen/include/xen/sched.h Wed Mar 05 16:22:57 2008 +0000 @@ -197,6 +197,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; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |