Merge branch 'linus' into x86/apic-cleanups
authorIngo Molnar <mingo@elte.hu>
Fri, 7 Jan 2011 13:14:15 +0000 (14:14 +0100)
committerIngo Molnar <mingo@elte.hu>
Fri, 7 Jan 2011 13:14:15 +0000 (14:14 +0100)
Conflicts:
arch/x86/include/asm/io_apic.h

Merge reason: Resolve the conflict, update to a more recent -rc base

Signed-off-by: Ingo Molnar <mingo@elte.hu>
1  2 
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/platform/sfi/sfi.c

@@@ -198,6 -198,11 +198,11 @@@ static void __cpuinit acpi_register_lap
  {
        unsigned int ver = 0;
  
+       if (id >= (MAX_LOCAL_APIC-1)) {
+               printk(KERN_INFO PREFIX "skipped apicid that is too big\n");
+               return;
+       }
        if (!enabled) {
                ++disabled_cpus;
                return;
@@@ -847,6 -852,18 +852,6 @@@ static int __init acpi_parse_fadt(struc
   * returns 0 on success, < 0 on error
   */
  
 -static void __init acpi_register_lapic_address(unsigned long address)
 -{
 -      mp_lapic_addr = address;
 -
 -      set_fixmap_nocache(FIX_APIC_BASE, address);
 -      if (boot_cpu_physical_apicid == -1U) {
 -              boot_cpu_physical_apicid  = read_apic_id();
 -              apic_version[boot_cpu_physical_apicid] =
 -                       GET_APIC_VERSION(apic_read(APIC_LVR));
 -      }
 -}
 -
  static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
  {
        int count;
                return count;
        }
  
 -      acpi_register_lapic_address(acpi_lapic_addr);
 +      register_lapic_address(acpi_lapic_addr);
  
        return count;
  }
@@@ -895,16 -912,16 +900,16 @@@ static int __init acpi_parse_madt_lapic
                return count;
        }
  
 -      acpi_register_lapic_address(acpi_lapic_addr);
 +      register_lapic_address(acpi_lapic_addr);
  
        count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
-                                     acpi_parse_sapic, MAX_APICS);
+                                     acpi_parse_sapic, MAX_LOCAL_APIC);
  
        if (!count) {
                x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
-                                               acpi_parse_x2apic, MAX_APICS);
+                                       acpi_parse_x2apic, MAX_LOCAL_APIC);
                count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
-                                             acpi_parse_lapic, MAX_APICS);
+                                       acpi_parse_lapic, MAX_LOCAL_APIC);
        }
        if (!count && !x2count) {
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
  extern int es7000_plat;
  #endif
  
 -static void assign_to_mp_irq(struct mpc_intsrc *m,
 -                                  struct mpc_intsrc *mp_irq)
 -{
 -      memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
 -}
 -
 -static int mp_irq_cmp(struct mpc_intsrc *mp_irq,
 -                              struct mpc_intsrc *m)
 -{
 -      return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
 -}
 -
 -static void save_mp_irq(struct mpc_intsrc *m)
 -{
 -      int i;
 -
 -      for (i = 0; i < mp_irq_entries; i++) {
 -              if (!mp_irq_cmp(&mp_irqs[i], m))
 -                      return;
 -      }
 -
 -      assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
 -      if (++mp_irq_entries == MAX_IRQ_SOURCES)
 -              panic("Max # of irq sources exceeded!!\n");
 -}
 -
  void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
  {
        int ioapic;
        mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */
        mp_irq.dstirq = pin;    /* INTIN# */
  
 -      save_mp_irq(&mp_irq);
 +      mp_save_irq(&mp_irq);
  
        isa_irq_to_gsi[bus_irq] = gsi;
  }
@@@ -1042,7 -1085,7 +1047,7 @@@ void __init mp_config_acpi_legacy_irqs(
                mp_irq.srcbusirq = i; /* Identity mapped */
                mp_irq.dstirq = pin;
  
 -              save_mp_irq(&mp_irq);
 +              mp_save_irq(&mp_irq);
        }
  }
  
@@@ -1079,7 -1122,7 +1084,7 @@@ static int mp_config_acpi_gsi(struct de
        mp_irq.dstapic = mp_ioapics[ioapic].apicid;
        mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
  
 -      save_mp_irq(&mp_irq);
 +      mp_save_irq(&mp_irq);
  #endif
        return 0;
  }
@@@ -31,7 -31,6 +31,6 @@@
  #include <linux/init.h>
  #include <linux/cpu.h>
  #include <linux/dmi.h>
- #include <linux/nmi.h>
  #include <linux/smp.h>
  #include <linux/mm.h>
  
@@@ -432,17 -431,18 +431,18 @@@ int setup_APIC_eilvt(u8 offset, u8 vect
        reserved = reserve_eilvt_offset(offset, new);
  
        if (reserved != new) {
-               pr_err(FW_BUG "cpu %d, try to setup vector 0x%x, but "
-                      "vector 0x%x was already reserved by another core, "
-                      "APIC%lX=0x%x\n",
-                      smp_processor_id(), new, reserved, reg, old);
+               pr_err(FW_BUG "cpu %d, try to use APIC%lX (LVT offset %d) for "
+                      "vector 0x%x, but the register is already in use for "
+                      "vector 0x%x on another cpu\n",
+                      smp_processor_id(), reg, offset, new, reserved);
                return -EINVAL;
        }
  
        if (!eilvt_entry_is_changeable(old, new)) {
-               pr_err(FW_BUG "cpu %d, try to setup vector 0x%x but "
-                      "register already in use, APIC%lX=0x%x\n",
-                      smp_processor_id(), new, reg, old);
+               pr_err(FW_BUG "cpu %d, try to use APIC%lX (LVT offset %d) for "
+                      "vector 0x%x, but the register is already in use for "
+                      "vector 0x%x on this cpu\n",
+                      smp_processor_id(), reg, offset, new, old);
                return -EBUSY;
        }
  
@@@ -799,11 -799,7 +799,7 @@@ void __init setup_boot_APIC_clock(void
         * PIT/HPET going.  Otherwise register lapic as a dummy
         * device.
         */
-       if (nmi_watchdog != NMI_IO_APIC)
-               lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
-       else
-               pr_warning("APIC timer registered as dummy,"
-                       " due to nmi_watchdog=%d!\n", nmi_watchdog);
+       lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
  
        /* Setup the lapic or request the broadcast */
        setup_APIC_timer();
@@@ -1195,15 -1191,12 +1191,15 @@@ static void __cpuinit lapic_setup_esr(v
                        oldvalue, value);
  }
  
 -
  /**
   * setup_local_APIC - setup the local APIC
 + *
 + * Used to setup local APIC while initializing BSP or bringin up APs.
 + * Always called with preemption disabled.
   */
  void __cpuinit setup_local_APIC(void)
  {
 +      int cpu = smp_processor_id();
        unsigned int value, queued;
        int i, j, acked = 0;
        unsigned long long tsc = 0, ntsc;
  #endif
        perf_events_lapic_init();
  
 -      preempt_disable();
 -
        /*
         * Double-check whether this APIC is really registered.
         * This is meaningless in clustered apic mode, so we skip it.
         * TODO: set up through-local-APIC from through-I/O-APIC? --macro
         */
        value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
 -      if (!smp_processor_id() && (pic_mode || !value)) {
 +      if (!cpu && (pic_mode || !value)) {
                value = APIC_DM_EXTINT;
 -              apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
 -                              smp_processor_id());
 +              apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu);
        } else {
                value = APIC_DM_EXTINT | APIC_LVT_MASKED;
 -              apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
 -                              smp_processor_id());
 +              apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", cpu);
        }
        apic_write(APIC_LVT0, value);
  
        /*
         * only the BP should see the LINT1 NMI signal, obviously.
         */
 -      if (!smp_processor_id())
 +      if (!cpu)
                value = APIC_DM_NMI;
        else
                value = APIC_DM_NMI | APIC_LVT_MASKED;
                value |= APIC_LVT_LEVEL_TRIGGER;
        apic_write(APIC_LVT1, value);
  
 -      preempt_enable();
 -
  #ifdef CONFIG_X86_MCE_INTEL
        /* Recheck CMCI information after local APIC is up on CPU #0 */
 -      if (smp_processor_id() == 0)
 +      if (!cpu)
                cmci_recheck();
  #endif
  }
@@@ -1384,8 -1383,15 +1380,15 @@@ void __cpuinit end_local_APIC_setup(voi
        }
  #endif
  
-       setup_apic_nmi_watchdog(NULL);
        apic_pm_activate();
+       /*
+        * Now that local APIC setup is completed for BP, configure the fault
+        * handling for interrupt remapping.
+        */
+       if (!smp_processor_id() && intr_remapping_enabled)
+               enable_drhd_fault_handling();
  }
  
  #ifdef CONFIG_X86_X2APIC
@@@ -1627,6 -1633,28 +1630,6 @@@ no_apic
  }
  #endif
  
 -#ifdef CONFIG_X86_64
 -void __init early_init_lapic_mapping(void)
 -{
 -      /*
 -       * If no local APIC can be found then go out
 -       * : it means there is no mpatable and MADT
 -       */
 -      if (!smp_found_config)
 -              return;
 -
 -      set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
 -      apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
 -                  APIC_BASE, mp_lapic_addr);
 -
 -      /*
 -       * Fetch the APIC ID of the BSP in case we have a
 -       * default configuration (or the MP table is broken).
 -       */
 -      boot_cpu_physical_apicid = read_apic_id();
 -}
 -#endif
 -
  /**
   * init_apic_mappings - initialize APIC mappings
   */
@@@ -1652,7 -1680,10 +1655,7 @@@ void __init init_apic_mappings(void
                 * acpi_register_lapic_address()
                 */
                if (!acpi_lapic && !smp_found_config)
 -                      set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
 -
 -              apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
 -                                      APIC_BASE, apic_phys);
 +                      register_lapic_address(apic_phys);
        }
  
        /*
        }
  }
  
 +void __init register_lapic_address(unsigned long address)
 +{
 +      mp_lapic_addr = address;
 +
 +      if (!x2apic_mode) {
 +              set_fixmap_nocache(FIX_APIC_BASE, address);
 +              apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
 +                          APIC_BASE, mp_lapic_addr);
 +      }
 +      if (boot_cpu_physical_apicid == -1U) {
 +              boot_cpu_physical_apicid  = read_apic_id();
 +              apic_version[boot_cpu_physical_apicid] =
 +                       GET_APIC_VERSION(apic_read(APIC_LVR));
 +      }
 +}
 +
  /*
   * This initializes the IO-APIC and APIC hardware if this is
   * a UP kernel.
   */
- int apic_version[MAX_APICS];
+ int apic_version[MAX_LOCAL_APIC];
  
  int __init APIC_init_uniprocessor(void)
  {
                setup_IO_APIC();
        else {
                nr_ioapics = 0;
-               localise_nmi_watchdog();
        }
- #else
-       localise_nmi_watchdog();
  #endif
  
        x86_init.timers.setup_percpu_clockev();
- #ifdef CONFIG_X86_64
-       check_nmi_watchdog();
- #endif
        return 0;
  }
  
@@@ -54,7 -54,6 +54,6 @@@
  #include <asm/dma.h>
  #include <asm/timer.h>
  #include <asm/i8259.h>
- #include <asm/nmi.h>
  #include <asm/msidef.h>
  #include <asm/hypertransport.h>
  #include <asm/setup.h>
@@@ -126,26 -125,6 +125,26 @@@ static int __init parse_noapic(char *st
  }
  early_param("noapic", parse_noapic);
  
 +/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */
 +void mp_save_irq(struct mpc_intsrc *m)
 +{
 +      int i;
 +
 +      apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"
 +              " IRQ %02x, APIC ID %x, APIC INT %02x\n",
 +              m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbus,
 +              m->srcbusirq, m->dstapic, m->dstirq);
 +
 +      for (i = 0; i < mp_irq_entries; i++) {
 +              if (!memcmp(&mp_irqs[i], m, sizeof(*m)))
 +                      return;
 +      }
 +
 +      memcpy(&mp_irqs[mp_irq_entries], m, sizeof(*m));
 +      if (++mp_irq_entries == MAX_IRQ_SOURCES)
 +              panic("Max # of irq sources exceeded!!\n");
 +}
 +
  struct irq_pin_list {
        int apic, pin;
        struct irq_pin_list *next;
@@@ -156,7 -135,6 +155,7 @@@ static struct irq_pin_list *alloc_irq_p
        return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node);
  }
  
 +
  /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
  #ifdef CONFIG_SPARSE_IRQ
  static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY];
@@@ -2028,12 -2006,9 +2027,12 @@@ void __init setup_ioapic_ids_from_mpc_n
                                                = mp_ioapics[apic_id].apicid;
  
                /*
 -               * Read the right value from the MPC table and
 -               * write it into the ID register.
 +               * Update the ID register according to the right value
 +               * from the MPC table if they are different.
                 */
 +              if (mp_ioapics[apic_id].apicid == reg_00.bits.ID)
 +                      continue;
 +
                apic_printk(APIC_VERBOSE, KERN_INFO
                        "...changing IO-APIC physical APIC ID to %d ...",
                        mp_ioapics[apic_id].apicid);
@@@ -2458,13 -2433,12 +2457,12 @@@ static void ack_apic_level(struct irq_d
  {
        struct irq_cfg *cfg = data->chip_data;
        int i, do_unmask_irq = 0, irq = data->irq;
-       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long v;
  
        irq_complete_move(cfg);
  #ifdef CONFIG_GENERIC_PENDING_IRQ
        /* If we are moving the irq we need to mask it */
-       if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
+       if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
                do_unmask_irq = 1;
                mask_ioapic(cfg);
        }
@@@ -2671,24 -2645,6 +2669,6 @@@ static void lapic_register_intr(int irq
                                      "edge");
  }
  
- static void __init setup_nmi(void)
- {
-       /*
-        * Dirty trick to enable the NMI watchdog ...
-        * We put the 8259A master into AEOI mode and
-        * unmask on all local APICs LVT0 as NMI.
-        *
-        * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
-        * is from Maciej W. Rozycki - so we do not have to EOI from
-        * the NMI handler or the timer interrupt.
-        */
-       apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
-       enable_NMI_through_LVT0();
-       apic_printk(APIC_VERBOSE, " done.\n");
- }
  /*
   * This looks a bit hackish but it's about the only one way of sending
   * a few INTA cycles to 8259As and any associated glue logic.  ICR does
@@@ -2794,15 -2750,6 +2774,6 @@@ static inline void __init check_timer(v
         */
        apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
        legacy_pic->init(1);
- #ifdef CONFIG_X86_32
-       {
-               unsigned int ver;
-               ver = apic_read(APIC_LVR);
-               ver = GET_APIC_VERSION(ver);
-               timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
-       }
- #endif
  
        pin1  = find_isa_irq_pin(0, mp_INT);
        apic1 = find_isa_irq_apic(0, mp_INT);
                                unmask_ioapic(cfg);
                }
                if (timer_irq_works()) {
-                       if (nmi_watchdog == NMI_IO_APIC) {
-                               setup_nmi();
-                               legacy_pic->unmask(0);
-                       }
                        if (disable_timer_pin_1 > 0)
                                clear_IO_APIC_pin(0, pin1);
                        goto out;
                if (timer_irq_works()) {
                        apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
                        timer_through_8259 = 1;
-                       if (nmi_watchdog == NMI_IO_APIC) {
-                               legacy_pic->mask(0);
-                               setup_nmi();
-                               legacy_pic->unmask(0);
-                       }
                        goto out;
                }
                /*
                apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
        }
  
-       if (nmi_watchdog == NMI_IO_APIC) {
-               apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
-                           "through the IO-APIC - disabling NMI Watchdog!\n");
-               nmi_watchdog = NMI_NONE;
-       }
- #ifdef CONFIG_X86_32
-       timer_ack = 0;
- #endif
        apic_printk(APIC_QUIET, KERN_INFO
                    "...trying to set up timer as Virtual Wire IRQ...\n");
  
@@@ -3441,6 -3370,7 +3394,7 @@@ dmar_msi_set_affinity(struct irq_data *
        msg.data |= MSI_DATA_VECTOR(cfg->vector);
        msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
        msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+       msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest);
  
        dmar_msi_write(irq, &msg);
  
@@@ -4133,7 -4063,8 +4087,8 @@@ void __init pre_init_apic_IRQ0(void
  
        printk(KERN_INFO "Early APIC setup for system timer0\n");
  #ifndef CONFIG_SMP
-       phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
+       physid_set_mask_of_physid(boot_cpu_physical_apicid,
+                                        &phys_cpu_present_map);
  #endif
        /* Make sure the irq descriptor is set up */
        cfg = alloc_irq_and_cfg_at(0, 0);
  #ifdef CONFIG_X86_LOCAL_APIC
  static unsigned long sfi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
  
 -static void __init mp_sfi_register_lapic_address(unsigned long address)
 -{
 -      mp_lapic_addr = address;
 -
 -      set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
 -      if (boot_cpu_physical_apicid == -1U)
 -              boot_cpu_physical_apicid = read_apic_id();
 -
 -      pr_info("Boot CPU = %d\n", boot_cpu_physical_apicid);
 -}
 -
  /* All CPUs enumerated by SFI must be present and enabled */
  static void __cpuinit mp_sfi_register_lapic(u8 id)
  {
-       if (MAX_APICS - id <= 0) {
+       if (MAX_LOCAL_APIC - id <= 0) {
                pr_warning("Processor #%d invalid (max %d)\n",
-                       id, MAX_APICS);
+                       id, MAX_LOCAL_APIC);
                return;
        }
  
@@@ -99,7 -110,7 +99,7 @@@ static int __init sfi_parse_ioapic(stru
  int __init sfi_platform_init(void)
  {
  #ifdef CONFIG_X86_LOCAL_APIC
 -      mp_sfi_register_lapic_address(sfi_lapic_addr);
 +      register_lapic_address(sfi_lapic_addr);
        sfi_table_parse(SFI_SIG_CPUS, NULL, NULL, sfi_parse_cpus);
  #endif
  #ifdef CONFIG_X86_IO_APIC