ia64/linux-2.6.18-xen.hg

changeset 466:26e1e96bd46a

x86 xen: 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@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Mar 05 11:09:41 2008 +0000 (2008-03-05)
parents 1cf7ba68d855
children e56eb4ff7606
files drivers/xen/core/smpboot.c include/xen/interface/vcpu.h
line diff
     1.1 --- a/drivers/xen/core/smpboot.c	Mon Mar 03 13:36:57 2008 +0000
     1.2 +++ b/drivers/xen/core/smpboot.c	Wed Mar 05 11:09:41 2008 +0000
     1.3 @@ -258,17 +258,28 @@ void __init smp_prepare_cpus(unsigned in
     1.4  {
     1.5  	unsigned int cpu;
     1.6  	struct task_struct *idle;
     1.7 +	int apicid, acpiid;
     1.8 +	struct vcpu_get_physid cpu_id;
     1.9  #ifdef __x86_64__
    1.10  	struct desc_ptr *gdt_descr;
    1.11  #else
    1.12  	struct Xgt_desc_struct *gdt_descr;
    1.13  #endif
    1.14  
    1.15 -	boot_cpu_data.apicid = 0;
    1.16 +	apicid = 0;
    1.17 +	if (HYPERVISOR_vcpu_op(VCPUOP_get_physid, 0, &cpu_id) == 0) {
    1.18 +		apicid = xen_vcpu_physid_to_x86_apicid(cpu_id.phys_id);
    1.19 +		acpiid = xen_vcpu_physid_to_x86_acpiid(cpu_id.phys_id);
    1.20 +#ifdef CONFIG_ACPI
    1.21 +		if (acpiid != 0xff)
    1.22 +			x86_acpiid_to_apicid[acpiid] = apicid;
    1.23 +#endif
    1.24 +	}
    1.25 +	boot_cpu_data.apicid = apicid;
    1.26  	cpu_data[0] = boot_cpu_data;
    1.27  
    1.28 -	cpu_2_logical_apicid[0] = 0;
    1.29 -	x86_cpu_to_apicid[0] = 0;
    1.30 +	cpu_2_logical_apicid[0] = apicid;
    1.31 +	x86_cpu_to_apicid[0] = apicid;
    1.32  
    1.33  	current_thread_info()->cpu = 0;
    1.34  
    1.35 @@ -312,11 +323,20 @@ void __init smp_prepare_cpus(unsigned in
    1.36  			(void *)gdt_descr->address,
    1.37  			XENFEAT_writable_descriptor_tables);
    1.38  
    1.39 +		apicid = cpu;
    1.40 +		if (HYPERVISOR_vcpu_op(VCPUOP_get_physid, cpu, &cpu_id) == 0) {
    1.41 +			apicid = xen_vcpu_physid_to_x86_apicid(cpu_id.phys_id);
    1.42 +			acpiid = xen_vcpu_physid_to_x86_acpiid(cpu_id.phys_id);
    1.43 +#ifdef CONFIG_ACPI
    1.44 +			if (acpiid != 0xff)
    1.45 +				x86_acpiid_to_apicid[acpiid] = apicid;
    1.46 +#endif
    1.47 +		}
    1.48  		cpu_data[cpu] = boot_cpu_data;
    1.49 -		cpu_data[cpu].apicid = cpu;
    1.50 +		cpu_data[cpu].apicid = apicid;
    1.51  
    1.52 -		cpu_2_logical_apicid[cpu] = cpu;
    1.53 -		x86_cpu_to_apicid[cpu] = cpu;
    1.54 +		cpu_2_logical_apicid[cpu] = apicid;
    1.55 +		x86_cpu_to_apicid[cpu] = apicid;
    1.56  
    1.57  		idle = fork_idle(cpu);
    1.58  		if (IS_ERR(idle))
     2.1 --- a/include/xen/interface/vcpu.h	Mon Mar 03 13:36:57 2008 +0000
     2.2 +++ b/include/xen/interface/vcpu.h	Wed Mar 05 11:09:41 2008 +0000
     2.3 @@ -170,7 +170,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_set_singles
     2.4   *
     2.5   * This may be called only once per vcpu.
     2.6   */
     2.7 -#define VCPUOP_register_vcpu_info   10  /* arg == struct vcpu_info */
     2.8 +#define VCPUOP_register_vcpu_info   10  /* arg == vcpu_register_vcpu_info_t */
     2.9  struct vcpu_register_vcpu_info {
    2.10      uint64_t mfn;    /* mfn of page to place vcpu_info */
    2.11      uint32_t offset; /* offset within page */
    2.12 @@ -182,6 +182,22 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_register_vc
    2.13  /* Send an NMI to the specified VCPU. @extra_arg == NULL. */
    2.14  #define VCPUOP_send_nmi             11
    2.15  
    2.16 +/* 
    2.17 + * Get the physical ID information for a pinned vcpu's underlying physical
    2.18 + * processor.  The physical ID informmation is architecture-specific.
    2.19 + * On x86: id[7:0]=apic_id, id[15:8]=acpi_id, id[63:16]=mbz,
    2.20 + *         and an unavailable identifier is returned as 0xff.
    2.21 + * This command returns -EINVAL if it is not a valid operation for this VCPU.
    2.22 + */
    2.23 +#define VCPUOP_get_physid           12 /* arg == vcpu_get_physid_t */
    2.24 +struct vcpu_get_physid {
    2.25 +    uint64_t phys_id;
    2.26 +};
    2.27 +typedef struct vcpu_get_physid vcpu_get_physid_t;
    2.28 +DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_t);
    2.29 +#define xen_vcpu_physid_to_x86_apicid(physid) ((uint8_t)((physid)>>0))
    2.30 +#define xen_vcpu_physid_to_x86_acpiid(physid) ((uint8_t)((physid)>>8))
    2.31 +
    2.32  #endif /* __XEN_PUBLIC_VCPU_H__ */
    2.33  
    2.34  /*