File 19038-x86-no-apic.patch of Package xen

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1231930540 0
# Node ID 59274c49a0298fd73f60759c0842a293b5816057
# Parent  cc542ebe48539b9ca0534ca241209734234fdff2
x86: restore ability to work on systems without APIC

This got broken with the default-enabling of MSI. Apart from fixing
the base issue, the patch also addresses
- the 'i' command crashing where there is no IO-APIC,
- the 'i' command needlessly printing information for all 256 vectors
  when the use of IO-APIC(s) is disabled, and
- the need to specify both "nolapic" and "noapic" when "nolapic" alone
  should already have the intended effect.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

Index: xen-3.3.1-testing/xen/arch/x86/apic.c
===================================================================
--- xen-3.3.1-testing.orig/xen/arch/x86/apic.c
+++ xen-3.3.1-testing/xen/arch/x86/apic.c
@@ -40,7 +40,7 @@
 /*
  * Knob to control our willingness to enable the local APIC.
  */
-int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
 
 /*
  * Debug level
@@ -719,7 +719,7 @@ static void apic_pm_activate(void)
 static void __init lapic_disable(char *str)
 {
     enable_local_apic = -1;
-    clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+    setup_clear_cpu_cap(X86_FEATURE_APIC);
 }
 custom_param("nolapic", lapic_disable);
 
@@ -852,6 +852,7 @@ void __init init_apic_mappings(void)
     if (!smp_found_config && detect_init_APIC()) {
         apic_phys = __pa(alloc_xenheap_page());
         clear_page(__va(apic_phys));
+        msi_enable = 0;
     } else
         apic_phys = mp_lapic_addr;
 
@@ -1280,8 +1281,10 @@ int __init APIC_init_uniprocessor (void)
     if (enable_local_apic < 0)
         clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
 
-    if (!smp_found_config && !cpu_has_apic)
+    if (!smp_found_config && !cpu_has_apic) {
+        msi_enable = 0;
         return -1;
+    }
 
     /*
      * Complain if the BIOS pretends there is one.
@@ -1290,6 +1293,7 @@ int __init APIC_init_uniprocessor (void)
         printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                boot_cpu_physical_apicid);
         clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+        msi_enable = 0;
         return -1;
     }
 
Index: xen-3.3.1-testing/xen/arch/x86/cpu/common.c
===================================================================
--- xen-3.3.1-testing.orig/xen/arch/x86/cpu/common.c
+++ xen-3.3.1-testing/xen/arch/x86/cpu/common.c
@@ -29,6 +29,14 @@ struct cpu_dev * cpu_devs[X86_VENDOR_NUM
  */
 u64 host_pat = 0x050100070406;
 
+static unsigned int __cpuinitdata cleared_caps[NCAPINTS];
+
+void __init setup_clear_cpu_cap(unsigned int cap)
+{
+	__clear_bit(cap, boot_cpu_data.x86_capability);
+	__set_bit(cap, cleared_caps);
+}
+
 static void default_init(struct cpuinfo_x86 * c)
 {
 	/* Not much we can do here... */
@@ -235,6 +243,7 @@ static void __init early_cpu_detect(void
 		if (c->x86 >= 0x6)
 			c->x86_model += ((tfms >> 16) & 0xF) << 4;
 		c->x86_mask = tfms & 15;
+		cap0 &= ~cleared_caps[0];
 		if (cap0 & (1<<19))
 			c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;
 		c->x86_capability[0] = cap0; /* Added for Xen bootstrap */
@@ -395,6 +404,9 @@ void __cpuinit identify_cpu(struct cpuin
 	if (disable_pse)
 		clear_bit(X86_FEATURE_PSE, c->x86_capability);
 
+	for (i = 0 ; i < NCAPINTS ; ++i)
+		c->x86_capability[i] &= ~cleared_caps[i];
+
 	/* If the model name is still unset, do table lookup. */
 	if ( !c->x86_model_id[0] ) {
 		char *p;
Index: xen-3.3.1-testing/xen/arch/x86/io_apic.c
===================================================================
--- xen-3.3.1-testing.orig/xen/arch/x86/io_apic.c
+++ xen-3.3.1-testing/xen/arch/x86/io_apic.c
@@ -87,7 +87,9 @@ int disable_timer_pin_1 __initdata;
 
 static struct irq_pin_list {
     int apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
+} irq_2_pin[PIN_MAP_SIZE] = {
+    [0 ... PIN_MAP_SIZE-1].pin = -1
+};
 static int irq_2_pin_free_entry = NR_IRQS;
 
 int vector_irq[NR_VECTORS] __read_mostly = {
@@ -1020,11 +1022,6 @@ static void __init enable_IO_APIC(void)
     int i, apic;
     unsigned long flags;
 
-    for (i = 0; i < PIN_MAP_SIZE; i++) {
-        irq_2_pin[i].pin = -1;
-        irq_2_pin[i].next = 0;
-    }
-
     /* Initialise dynamic irq_2_pin free list. */
     for (i = NR_IRQS; i < PIN_MAP_SIZE; i++)
         irq_2_pin[i].next = i + 1;
Index: xen-3.3.1-testing/xen/include/asm-x86/processor.h
===================================================================
--- xen-3.3.1-testing.orig/xen/include/asm-x86/processor.h
+++ xen-3.3.1-testing/xen/include/asm-x86/processor.h
@@ -191,6 +191,7 @@ extern int phys_proc_id[NR_CPUS];
 extern int cpu_core_id[NR_CPUS];
 
 extern void identify_cpu(struct cpuinfo_x86 *);
+extern void setup_clear_cpu_cap(unsigned int);
 extern void print_cpu_info(struct cpuinfo_x86 *);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern void dodgy_tsc(void);
openSUSE Build Service is sponsored by