x86: Sanitize smp_record and move it to x86_init_ops
[safe/jmp/linux-2.6] / arch / x86 / kernel / apic / io_apic.c
index 5d5f412..d2ed6c5 100644 (file)
@@ -59,6 +59,7 @@
 #include <asm/setup.h>
 #include <asm/irq_remapping.h>
 #include <asm/hpet.h>
+#include <asm/hw_irq.h>
 #include <asm/uv/uv_hub.h>
 #include <asm/uv/uv_irq.h>
 
@@ -176,16 +177,18 @@ int __init arch_early_irq_init(void)
        struct irq_cfg *cfg;
        struct irq_desc *desc;
        int count;
+       int node;
        int i;
 
        cfg = irq_cfgx;
        count = ARRAY_SIZE(irq_cfgx);
+       node= cpu_to_node(boot_cpu_id);
 
        for (i = 0; i < count; i++) {
                desc = irq_to_desc(i);
                desc->chip_data = &cfg[i];
-               alloc_bootmem_cpumask_var(&cfg[i].domain);
-               alloc_bootmem_cpumask_var(&cfg[i].old_domain);
+               zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
+               zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
                if (i < NR_IRQS_LEGACY)
                        cpumask_setall(cfg[i].domain);
        }
@@ -459,7 +462,8 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
 static void
 __ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
 {
-       union entry_union eu;
+       union entry_union eu = {{0, 0}};
+
        eu.entry = e;
        io_apic_write(apic, 0x11 + 2*pin, eu.w2);
        io_apic_write(apic, 0x10 + 2*pin, eu.w1);
@@ -1096,8 +1100,7 @@ static int pin_2_irq(int idx, int apic, int pin)
  * Not an __init, possibly needed by modules
  */
 int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
-                               int *ioapic, int *ioapic_pin,
-                               int *trigger, int *polarity)
+                               struct io_apic_irq_attr *irq_attr)
 {
        int apic, i, best_guess = -1;
 
@@ -1127,10 +1130,10 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
                                continue;
 
                        if (pin == (mp_irqs[i].srcbusirq & 3)) {
-                               *ioapic = apic;
-                               *ioapic_pin = mp_irqs[i].dstirq;
-                               *trigger = irq_trigger(i);
-                               *polarity = irq_polarity(i);
+                               set_io_apic_irq_attr(irq_attr, apic,
+                                                    mp_irqs[i].dstirq,
+                                                    irq_trigger(i),
+                                                    irq_polarity(i));
                                return irq;
                        }
                        /*
@@ -1138,10 +1141,10 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
                         * best-guess fuzzy result for broken mptables.
                         */
                        if (best_guess < 0) {
-                               *ioapic = apic;
-                               *ioapic_pin = mp_irqs[i].dstirq;
-                               *trigger = irq_trigger(i);
-                               *polarity = irq_polarity(i);
+                               set_io_apic_irq_attr(irq_attr, apic,
+                                                    mp_irqs[i].dstirq,
+                                                    irq_trigger(i),
+                                                    irq_polarity(i));
                                best_guess = irq;
                        }
                }
@@ -1411,6 +1414,9 @@ int setup_ioapic_entry(int apic_id, int irq,
                irte.vector = vector;
                irte.dest_id = IRTE_DEST(destination);
 
+               /* Set source-id of interrupt request */
+               set_ioapic_sid(&irte, apic_id);
+
                modify_irte(irq, &irte);
 
                ir_entry->index2 = (index >> 15) & 0x1;
@@ -1538,7 +1544,10 @@ static void __init setup_IO_APIC_irqs(void)
                }
                cfg = desc->chip_data;
                add_pin_to_irq_node(cfg, node, apic_id, pin);
-               set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
+               /*
+                * don't mark it in pin_programmed, so later acpi could
+                * set it correctly when irq < 16
+                */
                setup_IO_APIC_irq(apic_id, pin, irq, desc,
                                irq_trigger(idx), irq_polarity(idx));
        }
@@ -1707,36 +1716,30 @@ __apicdebuginit(void) print_IO_APIC(void)
        return;
 }
 
-__apicdebuginit(void) print_APIC_bitfield(int base)
+__apicdebuginit(void) print_APIC_field(int base)
 {
-       unsigned int v;
-       int i, j;
+       int i;
 
        if (apic_verbosity == APIC_QUIET)
                return;
 
-       printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
-       for (i = 0; i < 8; i++) {
-               v = apic_read(base + i*0x10);
-               for (j = 0; j < 32; j++) {
-                       if (v & (1<<j))
-                               printk("1");
-                       else
-                               printk("0");
-               }
-               printk("\n");
-       }
+       printk(KERN_DEBUG);
+
+       for (i = 0; i < 8; i++)
+               printk(KERN_CONT "%08x", apic_read(base + i*0x10));
+
+       printk(KERN_CONT "\n");
 }
 
 __apicdebuginit(void) print_local_APIC(void *dummy)
 {
-       unsigned int v, ver, maxlvt;
+       unsigned int i, v, ver, maxlvt;
        u64 icr;
 
        if (apic_verbosity == APIC_QUIET)
                return;
 
-       printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
+       printk(KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
                smp_processor_id(), hard_smp_processor_id());
        v = apic_read(APIC_ID);
        printk(KERN_INFO "... APIC ID:      %08x (%01x)\n", v, read_apic_id());
@@ -1777,11 +1780,11 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
        printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
 
        printk(KERN_DEBUG "... APIC ISR field:\n");
-       print_APIC_bitfield(APIC_ISR);
+       print_APIC_field(APIC_ISR);
        printk(KERN_DEBUG "... APIC TMR field:\n");
-       print_APIC_bitfield(APIC_TMR);
+       print_APIC_field(APIC_TMR);
        printk(KERN_DEBUG "... APIC IRR field:\n");
-       print_APIC_bitfield(APIC_IRR);
+       print_APIC_field(APIC_IRR);
 
        if (APIC_INTEGRATED(ver)) {             /* !82489DX */
                if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
@@ -1818,6 +1821,18 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
        printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
        v = apic_read(APIC_TDCR);
        printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
+
+       if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
+               v = apic_read(APIC_EFEAT);
+               maxlvt = (v >> 16) & 0xff;
+               printk(KERN_DEBUG "... APIC EFEAT: %08x\n", v);
+               v = apic_read(APIC_ECTRL);
+               printk(KERN_DEBUG "... APIC ECTRL: %08x\n", v);
+               for (i = 0; i < maxlvt; i++) {
+                       v = apic_read(APIC_EILVTn(i));
+                       printk(KERN_DEBUG "... APIC EILVT%d: %08x\n", i, v);
+               }
+       }
        printk("\n");
 }
 
@@ -1866,6 +1881,11 @@ __apicdebuginit(void) print_PIC(void)
 __apicdebuginit(int) print_all_ICs(void)
 {
        print_PIC();
+
+       /* don't print out if apic is not there */
+       if (!cpu_has_apic || disable_apic)
+               return 0;
+
        print_all_local_APICs();
        print_IO_APIC();
 
@@ -1981,7 +2001,9 @@ void disable_IO_APIC(void)
        /*
         * Use virtual wire A mode when interrupt remapping is enabled.
         */
-       disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1);
+       if (cpu_has_apic)
+               disconnect_bsp_APIC(!intr_remapping_enabled &&
+                               ioapic_i8259.pin != -1);
 }
 
 #ifdef CONFIG_X86_32
@@ -3265,6 +3287,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
                irte.vector = cfg->vector;
                irte.dest_id = IRTE_DEST(dest);
 
+               /* Set source-id of interrupt request */
+               set_msi_sid(&irte, pdev);
+
                modify_irte(irq, &irte);
 
                msg->address_hi = MSI_ADDR_BASE_HI;
@@ -3545,7 +3570,7 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 
 #endif /* CONFIG_SMP */
 
-struct irq_chip dmar_msi_type = {
+static struct irq_chip dmar_msi_type = {
        .name = "DMAR_MSI",
        .unmask = dmar_msi_unmask,
        .mask = dmar_msi_mask,
@@ -3742,6 +3767,8 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
        unsigned long flags;
        int err;
 
+       BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
        cfg = irq_cfg(irq);
 
        err = assign_irq_vector(irq, cfg, eligible_cpu);
@@ -3755,19 +3782,20 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
 
        mmr_value = 0;
        entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
-       BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
-       entry->vector = cfg->vector;
-       entry->delivery_mode = apic->irq_delivery_mode;
-       entry->dest_mode = apic->irq_dest_mode;
-       entry->polarity = 0;
-       entry->trigger = 0;
-       entry->mask = 0;
-       entry->dest = apic->cpu_mask_to_apicid(eligible_cpu);
+       entry->vector           = cfg->vector;
+       entry->delivery_mode    = apic->irq_delivery_mode;
+       entry->dest_mode        = apic->irq_dest_mode;
+       entry->polarity         = 0;
+       entry->trigger          = 0;
+       entry->mask             = 0;
+       entry->dest             = apic->cpu_mask_to_apicid(eligible_cpu);
 
        mmr_pnode = uv_blade_to_pnode(mmr_blade);
        uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
 
+       if (cfg->move_in_progress)
+               send_cleanup_vector(cfg);
+
        return irq;
 }
 
@@ -3781,10 +3809,10 @@ void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
        struct uv_IO_APIC_route_entry *entry;
        int mmr_pnode;
 
+       BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
        mmr_value = 0;
        entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
-       BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
        entry->mask = 1;
 
        mmr_pnode = uv_blade_to_pnode(mmr_blade);
@@ -3848,13 +3876,16 @@ int __init arch_probe_nr_irqs(void)
 }
 #endif
 
-static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
-                                int triggering, int polarity)
+static int __io_apic_set_pci_routing(struct device *dev, int irq,
+                               struct io_apic_irq_attr *irq_attr)
 {
        struct irq_desc *desc;
        struct irq_cfg *cfg;
        int node;
+       int ioapic, pin;
+       int trigger, polarity;
 
+       ioapic = irq_attr->ioapic;
        if (!IO_APIC_IRQ(irq)) {
                apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
                        ioapic);
@@ -3872,6 +3903,10 @@ static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, in
                return 0;
        }
 
+       pin = irq_attr->ioapic_pin;
+       trigger = irq_attr->trigger;
+       polarity = irq_attr->polarity;
+
        /*
         * IRQs < 16 are already in the irq_2_pin[] map
         */
@@ -3880,20 +3915,22 @@ static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, in
                add_pin_to_irq_node(cfg, node, ioapic, pin);
        }
 
-       setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity);
+       setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity);
 
        return 0;
 }
 
-int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
-                                int triggering, int polarity)
+int io_apic_set_pci_routing(struct device *dev, int irq,
+                               struct io_apic_irq_attr *irq_attr)
 {
-
+       int ioapic, pin;
        /*
         * Avoid pin reprogramming.  PRTs typically include entries
         * with redundant pin->gsi mappings (but unique PCI devices);
         * we only program the IOAPIC on the first.
         */
+       ioapic = irq_attr->ioapic;
+       pin = irq_attr->ioapic_pin;
        if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) {
                pr_debug("Pin %d-%d already programmed\n",
                         mp_ioapics[ioapic].apicid, pin);
@@ -3901,8 +3938,7 @@ int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
        }
        set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed);
 
-       return __io_apic_set_pci_routing(dev, ioapic, pin, irq,
-                                        triggering, polarity);
+       return __io_apic_set_pci_routing(dev, irq, irq_attr);
 }
 
 /* --------------------------------------------------------------------------
@@ -3985,6 +4021,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
 
        return apic_id;
 }
+#endif
 
 int __init io_apic_get_version(int ioapic)
 {
@@ -3997,7 +4034,6 @@ int __init io_apic_get_version(int ioapic)
 
        return reg_01.bits.version;
 }
-#endif
 
 int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
 {
@@ -4148,28 +4184,20 @@ fake_ioapic_page:
        }
 }
 
-static int __init ioapic_insert_resources(void)
+void __init ioapic_insert_resources(void)
 {
        int i;
        struct resource *r = ioapic_resources;
 
        if (!r) {
-               if (nr_ioapics > 0) {
+               if (nr_ioapics > 0)
                        printk(KERN_ERR
                                "IO APIC resources couldn't be allocated.\n");
-                       return -1;
-               }
-               return 0;
+               return;
        }
 
        for (i = 0; i < nr_ioapics; i++) {
                insert_resource(&iomem_resource, r);
                r++;
        }
-
-       return 0;
 }
-
-/* Insert the IO APIC resources after PCI initialization has occured to handle
- * IO APICS that are mapped in on a BAR in PCI space. */
-late_initcall(ioapic_insert_resources);