Commit 3d9d62b9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Thomas Gleixner:

 - Add a missing NULL pointer check in free_irq()

 - Fix a memory leak/memory corruption in the generic irq chip

 - Add missing rcu annotations for radix tree access

 - Use ffs instead of fls when extracting data from a chip register in
   the MIPS GIC irq driver

 - Fix the unmasking of IPI interrupts in the MIPS GIC driver so they
   end up at the target CPU and not at CPU0

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  irq/generic-chip: Don't replace domain's name
  irqdomain: Add __rcu annotations to radix tree accessors
  irqchip/mips-gic: Use effective affinity to unmask
  irqchip/mips-gic: Fix shifts to extract register fields
  genirq: Check __free_irq() return value for NULL
parents 156069f8 72364d32
...@@ -175,14 +175,13 @@ static void gic_mask_irq(struct irq_data *d) ...@@ -175,14 +175,13 @@ static void gic_mask_irq(struct irq_data *d)
static void gic_unmask_irq(struct irq_data *d) static void gic_unmask_irq(struct irq_data *d)
{ {
struct cpumask *affinity = irq_data_get_affinity_mask(d);
unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
unsigned int cpu; unsigned int cpu;
write_gic_smask(intr); write_gic_smask(intr);
gic_clear_pcpu_masks(intr); gic_clear_pcpu_masks(intr);
cpu = cpumask_first_and(affinity, cpu_online_mask); cpu = cpumask_first(irq_data_get_effective_affinity_mask(d));
set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
} }
...@@ -420,13 +419,17 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, ...@@ -420,13 +419,17 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
irq_hw_number_t hw, unsigned int cpu) irq_hw_number_t hw, unsigned int cpu)
{ {
int intr = GIC_HWIRQ_TO_SHARED(hw); int intr = GIC_HWIRQ_TO_SHARED(hw);
struct irq_data *data;
unsigned long flags; unsigned long flags;
data = irq_get_irq_data(virq);
spin_lock_irqsave(&gic_lock, flags); spin_lock_irqsave(&gic_lock, flags);
write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
gic_clear_pcpu_masks(intr); gic_clear_pcpu_masks(intr);
set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
irq_data_update_effective_affinity(data, cpumask_of(cpu));
spin_unlock_irqrestore(&gic_lock, flags); spin_unlock_irqrestore(&gic_lock, flags);
return 0; return 0;
...@@ -645,7 +648,7 @@ static int __init gic_of_init(struct device_node *node, ...@@ -645,7 +648,7 @@ static int __init gic_of_init(struct device_node *node,
/* Find the first available CPU vector. */ /* Find the first available CPU vector. */
i = 0; i = 0;
reserved = (C_SW0 | C_SW1) >> __fls(C_SW0); reserved = (C_SW0 | C_SW1) >> __ffs(C_SW0);
while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
i++, &cpu_vec)) i++, &cpu_vec))
reserved |= BIT(cpu_vec); reserved |= BIT(cpu_vec);
...@@ -684,11 +687,11 @@ static int __init gic_of_init(struct device_node *node, ...@@ -684,11 +687,11 @@ static int __init gic_of_init(struct device_node *node,
gicconfig = read_gic_config(); gicconfig = read_gic_config();
gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS); gic_shared_intrs >>= __ffs(GIC_CONFIG_NUMINTERRUPTS);
gic_shared_intrs = (gic_shared_intrs + 1) * 8; gic_shared_intrs = (gic_shared_intrs + 1) * 8;
gic_vpes = gicconfig & GIC_CONFIG_PVPS; gic_vpes = gicconfig & GIC_CONFIG_PVPS;
gic_vpes >>= __fls(GIC_CONFIG_PVPS); gic_vpes >>= __ffs(GIC_CONFIG_PVPS);
gic_vpes = gic_vpes + 1; gic_vpes = gic_vpes + 1;
if (cpu_has_veic) { if (cpu_has_veic) {
......
...@@ -322,7 +322,6 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip, ...@@ -322,7 +322,6 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
/* Calc pointer to the next generic chip */ /* Calc pointer to the next generic chip */
tmp += sizeof(*gc) + num_ct * sizeof(struct irq_chip_type); tmp += sizeof(*gc) + num_ct * sizeof(struct irq_chip_type);
} }
d->name = name;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips); EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips);
......
...@@ -945,7 +945,7 @@ static int virq_debug_show(struct seq_file *m, void *private) ...@@ -945,7 +945,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
struct irq_desc *desc; struct irq_desc *desc;
struct irq_domain *domain; struct irq_domain *domain;
struct radix_tree_iter iter; struct radix_tree_iter iter;
void **slot; void __rcu **slot;
int i; int i;
seq_printf(m, " %-16s %-6s %-10s %-10s %s\n", seq_printf(m, " %-16s %-6s %-10s %-10s %s\n",
...@@ -1453,7 +1453,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, ...@@ -1453,7 +1453,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
/* The irq_data was moved, fix the revmap to refer to the new location */ /* The irq_data was moved, fix the revmap to refer to the new location */
static void irq_domain_fix_revmap(struct irq_data *d) static void irq_domain_fix_revmap(struct irq_data *d)
{ {
void **slot; void __rcu **slot;
if (d->hwirq < d->domain->revmap_size) if (d->hwirq < d->domain->revmap_size)
return; /* Not using radix tree. */ return; /* Not using radix tree. */
......
...@@ -1643,6 +1643,10 @@ const void *free_irq(unsigned int irq, void *dev_id) ...@@ -1643,6 +1643,10 @@ const void *free_irq(unsigned int irq, void *dev_id)
#endif #endif
action = __free_irq(irq, dev_id); action = __free_irq(irq, dev_id);
if (!action)
return NULL;
devname = action->name; devname = action->name;
kfree(action); kfree(action);
return devname; return devname;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment