.. | .. |
---|
78 | 78 | #define for_each_irq_pin(entry, head) \ |
---|
79 | 79 | list_for_each_entry(entry, &head, list) |
---|
80 | 80 | |
---|
81 | | -static DEFINE_RAW_SPINLOCK(ioapic_lock); |
---|
| 81 | +static DEFINE_HARD_SPINLOCK(ioapic_lock); |
---|
82 | 82 | static DEFINE_MUTEX(ioapic_mutex); |
---|
83 | 83 | static unsigned int ioapic_dynirq_base; |
---|
84 | 84 | static int ioapic_initialized; |
---|
.. | .. |
---|
1634 | 1634 | return 1; |
---|
1635 | 1635 | |
---|
1636 | 1636 | local_save_flags(flags); |
---|
1637 | | - local_irq_enable(); |
---|
| 1637 | + local_irq_enable_full(); |
---|
1638 | 1638 | |
---|
1639 | 1639 | if (boot_cpu_has(X86_FEATURE_TSC)) |
---|
1640 | 1640 | delay_with_tsc(); |
---|
.. | .. |
---|
1642 | 1642 | delay_without_tsc(); |
---|
1643 | 1643 | |
---|
1644 | 1644 | local_irq_restore(flags); |
---|
| 1645 | + if (raw_irqs_disabled_flags(flags)) |
---|
| 1646 | + hard_local_irq_disable(); |
---|
1645 | 1647 | |
---|
1646 | 1648 | /* |
---|
1647 | 1649 | * Expect a few ticks at least, to be sure some possible |
---|
.. | .. |
---|
1722 | 1724 | return false; |
---|
1723 | 1725 | } |
---|
1724 | 1726 | |
---|
| 1727 | +static inline void do_prepare_move(struct irq_data *data) |
---|
| 1728 | +{ |
---|
| 1729 | + if (!irqd_irq_masked(data)) |
---|
| 1730 | + mask_ioapic_irq(data); |
---|
| 1731 | +} |
---|
| 1732 | + |
---|
| 1733 | +#ifdef CONFIG_IRQ_PIPELINE |
---|
| 1734 | + |
---|
| 1735 | +static inline void ioapic_finish_move(struct irq_data *data, bool moveit); |
---|
| 1736 | + |
---|
| 1737 | +static void ioapic_deferred_irq_move(struct irq_work *work) |
---|
| 1738 | +{ |
---|
| 1739 | + struct irq_data *data; |
---|
| 1740 | + struct irq_desc *desc; |
---|
| 1741 | + unsigned long flags; |
---|
| 1742 | + |
---|
| 1743 | + data = container_of(work, struct irq_data, move_work); |
---|
| 1744 | + desc = irq_data_to_desc(data); |
---|
| 1745 | + raw_spin_lock_irqsave(&desc->lock, flags); |
---|
| 1746 | + do_prepare_move(data); |
---|
| 1747 | + ioapic_finish_move(data, true); |
---|
| 1748 | + raw_spin_unlock_irqrestore(&desc->lock, flags); |
---|
| 1749 | +} |
---|
| 1750 | + |
---|
| 1751 | +static inline bool __ioapic_prepare_move(struct irq_data *data) |
---|
| 1752 | +{ |
---|
| 1753 | + init_irq_work(&data->move_work, ioapic_deferred_irq_move); |
---|
| 1754 | + irq_work_queue(&data->move_work); |
---|
| 1755 | + |
---|
| 1756 | + return false; /* Postpone ioapic_finish_move(). */ |
---|
| 1757 | +} |
---|
| 1758 | + |
---|
| 1759 | +#else /* !CONFIG_IRQ_PIPELINE */ |
---|
| 1760 | + |
---|
| 1761 | +static inline bool __ioapic_prepare_move(struct irq_data *data) |
---|
| 1762 | +{ |
---|
| 1763 | + do_prepare_move(data); |
---|
| 1764 | + |
---|
| 1765 | + return true; |
---|
| 1766 | +} |
---|
| 1767 | + |
---|
| 1768 | +#endif |
---|
| 1769 | + |
---|
1725 | 1770 | static inline bool ioapic_prepare_move(struct irq_data *data) |
---|
1726 | 1771 | { |
---|
1727 | 1772 | /* If we are moving the IRQ we need to mask it */ |
---|
1728 | | - if (unlikely(irqd_is_setaffinity_pending(data))) { |
---|
1729 | | - if (!irqd_irq_masked(data)) |
---|
1730 | | - mask_ioapic_irq(data); |
---|
1731 | | - return true; |
---|
1732 | | - } |
---|
| 1773 | + if (irqd_is_setaffinity_pending(data) && |
---|
| 1774 | + !irqd_is_setaffinity_blocked(data)) |
---|
| 1775 | + return __ioapic_prepare_move(data); |
---|
| 1776 | + |
---|
1733 | 1777 | return false; |
---|
1734 | 1778 | } |
---|
1735 | 1779 | |
---|
.. | .. |
---|
1828 | 1872 | * We must acknowledge the irq before we move it or the acknowledge will |
---|
1829 | 1873 | * not propagate properly. |
---|
1830 | 1874 | */ |
---|
1831 | | - ack_APIC_irq(); |
---|
| 1875 | + __ack_APIC_irq(); |
---|
1832 | 1876 | |
---|
1833 | 1877 | /* |
---|
1834 | 1878 | * Tail end of clearing remote IRR bit (either by delivering the EOI |
---|
.. | .. |
---|
1949 | 1993 | .irq_retrigger = irq_chip_retrigger_hierarchy, |
---|
1950 | 1994 | .irq_get_irqchip_state = ioapic_irq_get_chip_state, |
---|
1951 | 1995 | .flags = IRQCHIP_SKIP_SET_WAKE | |
---|
1952 | | - IRQCHIP_AFFINITY_PRE_STARTUP, |
---|
| 1996 | + IRQCHIP_AFFINITY_PRE_STARTUP | |
---|
| 1997 | + IRQCHIP_PIPELINE_SAFE, |
---|
1953 | 1998 | }; |
---|
1954 | 1999 | |
---|
1955 | 2000 | static struct irq_chip ioapic_ir_chip __read_mostly = { |
---|
.. | .. |
---|
1963 | 2008 | .irq_retrigger = irq_chip_retrigger_hierarchy, |
---|
1964 | 2009 | .irq_get_irqchip_state = ioapic_irq_get_chip_state, |
---|
1965 | 2010 | .flags = IRQCHIP_SKIP_SET_WAKE | |
---|
1966 | | - IRQCHIP_AFFINITY_PRE_STARTUP, |
---|
| 2011 | + IRQCHIP_AFFINITY_PRE_STARTUP | |
---|
| 2012 | + IRQCHIP_PIPELINE_SAFE, |
---|
1967 | 2013 | }; |
---|
1968 | 2014 | |
---|
1969 | 2015 | static inline void init_IO_APIC_traps(void) |
---|
.. | .. |
---|
2010 | 2056 | |
---|
2011 | 2057 | static void ack_lapic_irq(struct irq_data *data) |
---|
2012 | 2058 | { |
---|
2013 | | - ack_APIC_irq(); |
---|
| 2059 | + __ack_APIC_irq(); |
---|
2014 | 2060 | } |
---|
2015 | 2061 | |
---|
2016 | 2062 | static struct irq_chip lapic_chip __read_mostly = { |
---|
.. | .. |
---|
2018 | 2064 | .irq_mask = mask_lapic_irq, |
---|
2019 | 2065 | .irq_unmask = unmask_lapic_irq, |
---|
2020 | 2066 | .irq_ack = ack_lapic_irq, |
---|
| 2067 | + .flags = IRQCHIP_PIPELINE_SAFE, |
---|
2021 | 2068 | }; |
---|
2022 | 2069 | |
---|
2023 | 2070 | static void lapic_register_intr(int irq) |
---|
.. | .. |
---|
2135 | 2182 | if (!global_clock_event) |
---|
2136 | 2183 | return; |
---|
2137 | 2184 | |
---|
2138 | | - local_irq_save(flags); |
---|
| 2185 | + local_irq_save_full(flags); |
---|
2139 | 2186 | |
---|
2140 | 2187 | /* |
---|
2141 | 2188 | * get/set the timer IRQ vector: |
---|
.. | .. |
---|
2203 | 2250 | goto out; |
---|
2204 | 2251 | } |
---|
2205 | 2252 | panic_if_irq_remap("timer doesn't work through Interrupt-remapped IO-APIC"); |
---|
2206 | | - local_irq_disable(); |
---|
| 2253 | + local_irq_disable_full(); |
---|
2207 | 2254 | clear_IO_APIC_pin(apic1, pin1); |
---|
2208 | 2255 | if (!no_pin1) |
---|
2209 | 2256 | apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: " |
---|
.. | .. |
---|
2227 | 2274 | /* |
---|
2228 | 2275 | * Cleanup, just in case ... |
---|
2229 | 2276 | */ |
---|
2230 | | - local_irq_disable(); |
---|
| 2277 | + local_irq_disable_full(); |
---|
2231 | 2278 | legacy_pic->mask(0); |
---|
2232 | 2279 | clear_IO_APIC_pin(apic2, pin2); |
---|
2233 | 2280 | apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); |
---|
.. | .. |
---|
2244 | 2291 | apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); |
---|
2245 | 2292 | goto out; |
---|
2246 | 2293 | } |
---|
2247 | | - local_irq_disable(); |
---|
| 2294 | + local_irq_disable_full(); |
---|
2248 | 2295 | legacy_pic->mask(0); |
---|
2249 | 2296 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); |
---|
2250 | 2297 | apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); |
---|
.. | .. |
---|
2263 | 2310 | apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); |
---|
2264 | 2311 | goto out; |
---|
2265 | 2312 | } |
---|
2266 | | - local_irq_disable(); |
---|
| 2313 | + local_irq_disable_full(); |
---|
2267 | 2314 | apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n"); |
---|
2268 | 2315 | if (apic_is_x2apic_enabled()) |
---|
2269 | 2316 | apic_printk(APIC_QUIET, KERN_INFO |
---|
.. | .. |
---|
2272 | 2319 | panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " |
---|
2273 | 2320 | "report. Then try booting with the 'noapic' option.\n"); |
---|
2274 | 2321 | out: |
---|
2275 | | - local_irq_restore(flags); |
---|
| 2322 | + local_irq_restore_full(flags); |
---|
2276 | 2323 | } |
---|
2277 | 2324 | |
---|
2278 | 2325 | /* |
---|
.. | .. |
---|
3018 | 3065 | cfg = irqd_cfg(irq_data); |
---|
3019 | 3066 | add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin); |
---|
3020 | 3067 | |
---|
3021 | | - local_irq_save(flags); |
---|
| 3068 | + local_irq_save_full(flags); |
---|
3022 | 3069 | if (info->ioapic.entry) |
---|
3023 | 3070 | mp_setup_entry(cfg, data, info->ioapic.entry); |
---|
3024 | 3071 | mp_register_handler(virq, data->trigger); |
---|
3025 | 3072 | if (virq < nr_legacy_irqs()) |
---|
3026 | 3073 | legacy_pic->mask(virq); |
---|
3027 | | - local_irq_restore(flags); |
---|
| 3074 | + local_irq_restore_full(flags); |
---|
3028 | 3075 | |
---|
3029 | 3076 | apic_printk(APIC_VERBOSE, KERN_DEBUG |
---|
3030 | 3077 | "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i Dest:%d)\n", |
---|