mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
xen/apic: Return the APIC ID (and version) for CPU 0.
On x86_64 on AMD machines where the first APIC_ID is not zero, we get: ACPI: LAPIC (acpi_id[0x01] lapic_id[0x10] enabled) BIOS bug: APIC version is 0 for CPU 1/0x10, fixing up to 0x10 BIOS bug: APIC version mismatch, boot CPU: 0, CPU 1: version 10 which means that when the ACPI processor driver loads and tries to parse the _Pxx states it fails to do as, as it ends up calling acpi_get_cpuid which does this: for_each_possible_cpu(i) { if (cpu_physical_id(i) == apic_id) return i; } And the bootup CPU, has not been found so it fails and returns -1 for the first CPU - which then subsequently in the loop that "acpi_processor_get_info" does results in returning an error, which means that "acpi_processor_add" failing and per_cpu(processor) is never set (and is NULL). That means that when xen-acpi-processor tries to load (much much later on) and parse the P-states it gets -ENODEV from acpi_processor_register_performance() (which tries to read the per_cpu(processor)) and fails to parse the data. Reported-by-and-Tested-by: Stefan Bader <stefan.bader@canonical.com> Suggested-by: Boris Ostrovsky <boris.ostrovsky@amd.com> [v2: Bit-shift APIC ID by 24 bits] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This commit is contained in:
parent
a7a97c6394
commit
558daa289a
1 changed files with 34 additions and 1 deletions
|
@ -809,9 +809,40 @@ static void xen_io_delay(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
static unsigned long xen_set_apic_id(unsigned int x)
|
||||
{
|
||||
WARN_ON(1);
|
||||
return x;
|
||||
}
|
||||
static unsigned int xen_get_apic_id(unsigned long x)
|
||||
{
|
||||
return ((x)>>24) & 0xFFu;
|
||||
}
|
||||
static u32 xen_apic_read(u32 reg)
|
||||
{
|
||||
return 0;
|
||||
struct xen_platform_op op = {
|
||||
.cmd = XENPF_get_cpuinfo,
|
||||
.interface_version = XENPF_INTERFACE_VERSION,
|
||||
.u.pcpu_info.xen_cpuid = 0,
|
||||
};
|
||||
int ret = 0;
|
||||
|
||||
/* Shouldn't need this as APIC is turned off for PV, and we only
|
||||
* get called on the bootup processor. But just in case. */
|
||||
if (!xen_initial_domain() || smp_processor_id())
|
||||
return 0;
|
||||
|
||||
if (reg == APIC_LVR)
|
||||
return 0x10;
|
||||
|
||||
if (reg != APIC_ID)
|
||||
return 0;
|
||||
|
||||
ret = HYPERVISOR_dom0_op(&op);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return op.u.pcpu_info.apic_id << 24;
|
||||
}
|
||||
|
||||
static void xen_apic_write(u32 reg, u32 val)
|
||||
|
@ -849,6 +880,8 @@ static void set_xen_basic_apic_ops(void)
|
|||
apic->icr_write = xen_apic_icr_write;
|
||||
apic->wait_icr_idle = xen_apic_wait_icr_idle;
|
||||
apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
|
||||
apic->set_apic_id = xen_set_apic_id;
|
||||
apic->get_apic_id = xen_get_apic_id;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue