102 lines
2.9 KiB
Diff
102 lines
2.9 KiB
Diff
|
# HG changeset patch
|
||
|
# User Keir Fraser <keir@xen.org>
|
||
|
# Date 1294746050 0
|
||
|
# Node ID 2ff199e2842b7e4f08ea99558afc32536a77280c
|
||
|
# Parent ca10302ac2859b43a41afe425d79ae0df29f2a9c
|
||
|
x86: restore x2apic pre-enabled check logic
|
||
|
References: bnc#656369, bnc#658704
|
||
|
|
||
|
c/s 22475 removed the early checking without replacement, neglecting
|
||
|
the fact that x2apic_enabled must be set early for APIC register
|
||
|
accesses done during second stage ACPI table parsing (rooted at
|
||
|
acpi_boot_init()) to work correctly. Without this, particularly
|
||
|
determination of the boot CPU won't work, resulting in an attempt to
|
||
|
bring up that CPU again as a secondary one (which fails).
|
||
|
|
||
|
Restore the functionality, now calling it from generic_apic_probe().
|
||
|
|
||
|
Signed-off-by: Jan Beulich <jbeulich@novell.com>
|
||
|
|
||
|
--- a/xen/arch/x86/apic.c
|
||
|
+++ b/xen/arch/x86/apic.c
|
||
|
@@ -947,7 +947,6 @@ no_apic:
|
||
|
void x2apic_setup(void)
|
||
|
{
|
||
|
struct IO_APIC_route_entry **ioapic_entries = NULL;
|
||
|
- u32 lo, hi;
|
||
|
|
||
|
if ( smp_processor_id() != 0 )
|
||
|
{
|
||
|
@@ -959,14 +958,6 @@ void x2apic_setup(void)
|
||
|
if ( !cpu_has_x2apic )
|
||
|
return;
|
||
|
|
||
|
- /* Check whether x2apic mode was already enabled by the BIOS. */
|
||
|
- rdmsr(MSR_IA32_APICBASE, lo, hi);
|
||
|
- if ( lo & MSR_IA32_APICBASE_EXTD )
|
||
|
- {
|
||
|
- printk("x2APIC mode is already enabled by BIOS.\n");
|
||
|
- x2apic_enabled = 1;
|
||
|
- }
|
||
|
-
|
||
|
if ( !opt_x2apic )
|
||
|
{
|
||
|
if ( !x2apic_enabled )
|
||
|
--- a/xen/arch/x86/genapic/probe.c
|
||
|
+++ b/xen/arch/x86/genapic/probe.c
|
||
|
@@ -59,8 +59,10 @@ custom_param("apic", genapic_apic_force)
|
||
|
|
||
|
void __init generic_apic_probe(void)
|
||
|
{
|
||
|
- int i;
|
||
|
- int changed = cmdline_apic = (genapic != NULL);
|
||
|
+ int i, changed;
|
||
|
+
|
||
|
+ check_x2apic_preenabled();
|
||
|
+ cmdline_apic = changed = (genapic != NULL);
|
||
|
|
||
|
for (i = 0; !changed && apic_probe[i]; i++) {
|
||
|
if (apic_probe[i]->probe()) {
|
||
|
--- a/xen/arch/x86/genapic/x2apic.c
|
||
|
+++ b/xen/arch/x86/genapic/x2apic.c
|
||
|
@@ -20,6 +20,8 @@
|
||
|
#include <xen/cpumask.h>
|
||
|
#include <asm/apicdef.h>
|
||
|
#include <asm/genapic.h>
|
||
|
+#include <asm/msr.h>
|
||
|
+#include <asm/processor.h>
|
||
|
#include <xen/smp.h>
|
||
|
#include <asm/mach-default/mach_mpparse.h>
|
||
|
|
||
|
@@ -134,3 +136,20 @@ const struct genapic *apic_x2apic_probe(
|
||
|
{
|
||
|
return x2apic_phys ? &apic_x2apic_phys : &apic_x2apic_cluster;
|
||
|
}
|
||
|
+
|
||
|
+void __init check_x2apic_preenabled(void)
|
||
|
+{
|
||
|
+ u32 lo, hi;
|
||
|
+
|
||
|
+ if ( !cpu_has_x2apic )
|
||
|
+ return;
|
||
|
+
|
||
|
+ /* Check whether x2apic mode was already enabled by the BIOS. */
|
||
|
+ rdmsr(MSR_IA32_APICBASE, lo, hi);
|
||
|
+ if ( lo & MSR_IA32_APICBASE_EXTD )
|
||
|
+ {
|
||
|
+ printk("x2APIC mode is already enabled by BIOS.\n");
|
||
|
+ x2apic_enabled = 1;
|
||
|
+ genapic = apic_x2apic_probe();
|
||
|
+ }
|
||
|
+}
|
||
|
--- a/xen/include/asm-x86/apic.h
|
||
|
+++ b/xen/include/asm-x86/apic.h
|
||
|
@@ -25,6 +25,7 @@ extern int apic_verbosity;
|
||
|
extern int x2apic_enabled;
|
||
|
extern int directed_eoi_enabled;
|
||
|
|
||
|
+void check_x2apic_preenabled(void);
|
||
|
void x2apic_setup(void);
|
||
|
const struct genapic *apic_x2apic_probe(void);
|
||
|
|