File 22789-i386-no-x2apic.patch of Package xen.import4929

# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1295625507 0
# Node ID 9bd5f65050f8014de7d0fcf9d89ed8c441f261fa
# Parent  5852612cd4c461e5219db73cc52de0c643c414e8
x86:x2apic: Disable x2apic on x86-32 permanently

x2apic initialization on x86_32 uses vcpu pointer before it is
initialized. As x2apic is unlikely to be used on x86_32, this patch
disables x2apic permanently on x86_32. It also asserts the sanity of
vcpu pointer before dereference to prevent further misuse.

Signed-off-by: Fengzhe Zhang <fengzhe.zhang@intel.com>

jb: Moved logic into check_x2apic_preenabled(), disabled dead code on
    x86_32.

--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -67,10 +67,12 @@ static int enable_local_apic __initdata 
  */
 int apic_verbosity;
 
+#ifndef __i386__
 static int opt_x2apic = 1;
 boolean_param("x2apic", opt_x2apic);
 
 int x2apic_enabled __read_mostly = 0;
+#endif
 int directed_eoi_enabled __read_mostly = 0;
 
 /*
@@ -956,6 +958,10 @@ void x2apic_setup(void)
     if ( !cpu_has_x2apic )
         return;
 
+#ifdef __i386__
+    BUG();
+#else
+
     if ( !opt_x2apic )
     {
         if ( !x2apic_enabled )
@@ -1017,6 +1023,7 @@ restore_out:
     unmask_8259A();
 
 out:
+#endif /* !__i386__ */
     if ( ioapic_entries )
         free_ioapic_entries(ioapic_entries);
 }
--- a/xen/arch/x86/genapic/x2apic.c
+++ b/xen/arch/x86/genapic/x2apic.c
@@ -25,6 +25,8 @@
 #include <xen/smp.h>
 #include <asm/mach-default/mach_mpparse.h>
 
+#ifndef __i386__
+
 static int x2apic_phys; /* By default we use logical cluster mode. */
 boolean_param("x2apic_phys", x2apic_phys);
 
@@ -137,6 +139,8 @@ const struct genapic *apic_x2apic_probe(
     return x2apic_phys ? &apic_x2apic_phys : &apic_x2apic_cluster;
 }
 
+#endif /* !__i386__ */
+
 void __init check_x2apic_preenabled(void)
 {
     u32 lo, hi;
@@ -149,7 +153,19 @@ void __init check_x2apic_preenabled(void
     if ( lo & MSR_IA32_APICBASE_EXTD )
     {
         printk("x2APIC mode is already enabled by BIOS.\n");
+#ifndef __i386__
         x2apic_enabled = 1;
         genapic = apic_x2apic_probe();
+#else
+        lo &= ~(MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD);
+        wrmsr(MSR_IA32_APICBASE, lo, hi);
+        lo |= MSR_IA32_APICBASE_ENABLE;
+        wrmsr(MSR_IA32_APICBASE, lo, hi);
+        printk("x2APIC disabled permanently on x86_32.\n");
+#endif
     }
+
+#ifdef __i386__
+    clear_bit(X86_FEATURE_X2APIC, boot_cpu_data.x86_capability);
+#endif
 }
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -824,6 +824,7 @@ out:
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
+#ifndef __i386__
 /*
  * This function is used to enable Interrutp remapping when
  * enable x2apic
@@ -880,6 +881,7 @@ int iommu_enable_IR(void)
 
     return 0;
 }
+#endif
 
 /*
  * This function is used to disable Interrutp remapping when
--- a/xen/include/asm-x86/apic.h
+++ b/xen/include/asm-x86/apic.h
@@ -22,7 +22,11 @@
 #define IO_APIC_REDIR_DEST_PHYSICAL	0x00000
 
 extern int apic_verbosity;
+#ifdef __i386__
+#define x2apic_enabled 0
+#else
 extern int x2apic_enabled;
+#endif
 extern int directed_eoi_enabled;
 
 void check_x2apic_preenabled(void);
openSUSE Build Service is sponsored by