Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'irq-urgent-2024-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Ingo Molnar:

- Fix x86 IRQ vector leak caused by a CPU offlining race

- Fix build failure in the riscv-imsic irqchip driver
caused by an API-change semantic conflict

- Fix use-after-free in irq_find_at_or_after()

* tag 'irq-urgent-2024-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
genirq/irqdesc: Prevent use-after-free in irq_find_at_or_after()
genirq/cpuhotplug, x86/vector: Prevent vector leak during CPU offline
irqchip/riscv-imsic: Fixup riscv_ipi_set_virq_range() conflict

+18 -12
+6 -3
arch/x86/kernel/apic/vector.c
··· 1035 1035 add_timer_on(&cl->timer, cpu); 1036 1036 } 1037 1037 } else { 1038 - apicd->prev_vector = 0; 1038 + pr_warn("IRQ %u schedule cleanup for offline CPU %u\n", apicd->irq, cpu); 1039 + free_moved_vector(apicd); 1039 1040 } 1040 1041 raw_spin_unlock(&vector_lock); 1041 1042 } ··· 1073 1072 */ 1074 1073 void irq_force_complete_move(struct irq_desc *desc) 1075 1074 { 1075 + unsigned int cpu = smp_processor_id(); 1076 1076 struct apic_chip_data *apicd; 1077 1077 struct irq_data *irqd; 1078 1078 unsigned int vector; ··· 1098 1096 goto unlock; 1099 1097 1100 1098 /* 1101 - * If prev_vector is empty, no action required. 1099 + * If prev_vector is empty or the descriptor is neither currently 1100 + * nor previously on the outgoing CPU no action required. 1102 1101 */ 1103 1102 vector = apicd->prev_vector; 1104 - if (!vector) 1103 + if (!vector || (apicd->cpu != cpu && apicd->prev_cpu != cpu)) 1105 1104 goto unlock; 1106 1105 1107 1106 /*
+8 -8
kernel/irq/cpuhotplug.c
··· 70 70 } 71 71 72 72 /* 73 + * Complete an eventually pending irq move cleanup. If this 74 + * interrupt was moved in hard irq context, then the vectors need 75 + * to be cleaned up. It can't wait until this interrupt actually 76 + * happens and this CPU was involved. 77 + */ 78 + irq_force_complete_move(desc); 79 + 80 + /* 73 81 * No move required, if: 74 82 * - Interrupt is per cpu 75 83 * - Interrupt is not started ··· 94 86 irq_fixup_move_pending(desc, false); 95 87 return false; 96 88 } 97 - 98 - /* 99 - * Complete an eventually pending irq move cleanup. If this 100 - * interrupt was moved in hard irq context, then the vectors need 101 - * to be cleaned up. It can't wait until this interrupt actually 102 - * happens and this CPU was involved. 103 - */ 104 - irq_force_complete_move(desc); 105 89 106 90 /* 107 91 * If there is a setaffinity pending, then try to reuse the pending
+4 -1
kernel/irq/irqdesc.c
··· 160 160 static unsigned int irq_find_at_or_after(unsigned int offset) 161 161 { 162 162 unsigned long index = offset; 163 - struct irq_desc *desc = mt_find(&sparse_irqs, &index, nr_irqs); 163 + struct irq_desc *desc; 164 + 165 + guard(rcu)(); 166 + desc = mt_find(&sparse_irqs, &index, nr_irqs); 164 167 165 168 return desc ? irq_desc_get_irq(desc) : nr_irqs; 166 169 }