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-2023-03-05' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
"A set of updates for the interrupt susbsystem:

- Prevent possible NULL pointer derefences in
irq_data_get_affinity_mask() and irq_domain_create_hierarchy()

- Take the per device MSI lock before invoking code which relies on
it being hold

- Make sure that MSI descriptors are unreferenced before freeing
them. This was overlooked when the platform MSI code was converted
to use core infrastructure and results in a fals positive warning

- Remove dead code in the MSI subsystem

- Clarify the documentation for pci_msix_free_irq()

- More kobj_type constification"

* tag 'irq-urgent-2023-03-05' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
genirq/msi, platform-msi: Ensure that MSI descriptors are unreferenced
genirq/msi: Drop dead domain name assignment
irqdomain: Add missing NULL pointer check in irq_domain_create_hierarchy()
genirq/irqdesc: Make kobj_type structures constant
PCI/MSI: Clarify usage of pci_msix_free_irq()
genirq/msi: Take the per-device MSI lock before validating the control structure
genirq/ipi: Fix NULL pointer deref in irq_data_get_affinity_mask()

+44 -15
+1
drivers/base/platform-msi.c
··· 324 324 struct platform_msi_priv_data *data = domain->host_data; 325 325 326 326 msi_lock_descs(data->dev); 327 + msi_domain_depopulate_descs(data->dev, virq, nr_irqs); 327 328 irq_domain_free_irqs_common(domain, virq, nr_irqs); 328 329 msi_free_msi_descs_range(data->dev, virq, virq + nr_irqs - 1); 329 330 msi_unlock_descs(data->dev);
+2 -2
drivers/pci/msi/api.c
··· 163 163 164 164 /** 165 165 * pci_msix_free_irq - Free an interrupt on a PCI/MSIX interrupt domain 166 - * which was allocated via pci_msix_alloc_irq_at() 167 166 * 168 167 * @dev: The PCI device to operate on 169 168 * @map: A struct msi_map describing the interrupt to free 170 - * as returned from the allocation function. 169 + * 170 + * Undo an interrupt vector allocation. Does not disable MSI-X. 171 171 */ 172 172 void pci_msix_free_irq(struct pci_dev *dev, struct msi_map map) 173 173 {
+2
include/linux/msi.h
··· 635 635 int nvec, msi_alloc_info_t *args); 636 636 int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, 637 637 int virq, int nvec, msi_alloc_info_t *args); 638 + void msi_domain_depopulate_descs(struct device *dev, int virq, int nvec); 639 + 638 640 struct irq_domain * 639 641 __platform_msi_create_device_domain(struct device *dev, 640 642 unsigned int nvec,
+6 -2
kernel/irq/ipi.c
··· 188 188 static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data, 189 189 const struct cpumask *dest, unsigned int cpu) 190 190 { 191 - const struct cpumask *ipimask = irq_data_get_affinity_mask(data); 191 + const struct cpumask *ipimask; 192 192 193 - if (!chip || !ipimask) 193 + if (!chip || !data) 194 194 return -EINVAL; 195 195 196 196 if (!chip->ipi_send_single && !chip->ipi_send_mask) 197 197 return -EINVAL; 198 198 199 199 if (cpu >= nr_cpu_ids) 200 + return -EINVAL; 201 + 202 + ipimask = irq_data_get_affinity_mask(data); 203 + if (!ipimask) 200 204 return -EINVAL; 201 205 202 206 if (dest) {
+2 -2
kernel/irq/irqdesc.c
··· 277 277 }; 278 278 ATTRIBUTE_GROUPS(irq); 279 279 280 - static struct kobj_type irq_kobj_type = { 280 + static const struct kobj_type irq_kobj_type = { 281 281 .release = irq_kobj_release, 282 282 .sysfs_ops = &kobj_sysfs_ops, 283 283 .default_groups = irq_groups, ··· 335 335 336 336 #else /* !CONFIG_SYSFS */ 337 337 338 - static struct kobj_type irq_kobj_type = { 338 + static const struct kobj_type irq_kobj_type = { 339 339 .release = irq_kobj_release, 340 340 }; 341 341
+2 -1
kernel/irq/irqdomain.c
··· 1147 1147 domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data); 1148 1148 1149 1149 if (domain) { 1150 - domain->root = parent->root; 1150 + if (parent) 1151 + domain->root = parent->root; 1151 1152 domain->parent = parent; 1152 1153 domain->flags |= flags; 1153 1154
+29 -8
kernel/irq/msi.c
··· 830 830 domain = irq_domain_create_hierarchy(parent, flags | IRQ_DOMAIN_FLAG_MSI, 0, 831 831 fwnode, &msi_domain_ops, info); 832 832 833 - if (domain) { 834 - if (!domain->name && info->chip) 835 - domain->name = info->chip->name; 833 + if (domain) 836 834 irq_domain_update_bus_token(domain, info->bus_token); 837 - } 838 835 839 836 return domain; 840 837 } ··· 1081 1084 struct xarray *xa; 1082 1085 int ret, virq; 1083 1086 1084 - if (!msi_ctrl_valid(dev, &ctrl)) 1085 - return -EINVAL; 1086 - 1087 1087 msi_lock_descs(dev); 1088 + 1089 + if (!msi_ctrl_valid(dev, &ctrl)) { 1090 + ret = -EINVAL; 1091 + goto unlock; 1092 + } 1093 + 1088 1094 ret = msi_domain_add_simple_msi_descs(dev, &ctrl); 1089 1095 if (ret) 1090 1096 goto unlock; ··· 1109 1109 return 0; 1110 1110 1111 1111 fail: 1112 - for (--virq; virq >= virq_base; virq--) 1112 + for (--virq; virq >= virq_base; virq--) { 1113 + msi_domain_depopulate_descs(dev, virq, 1); 1113 1114 irq_domain_free_irqs_common(domain, virq, 1); 1115 + } 1114 1116 msi_domain_free_descs(dev, &ctrl); 1115 1117 unlock: 1116 1118 msi_unlock_descs(dev); 1117 1119 return ret; 1120 + } 1121 + 1122 + void msi_domain_depopulate_descs(struct device *dev, int virq_base, int nvec) 1123 + { 1124 + struct msi_ctrl ctrl = { 1125 + .domid = MSI_DEFAULT_DOMAIN, 1126 + .first = virq_base, 1127 + .last = virq_base + nvec - 1, 1128 + }; 1129 + struct msi_desc *desc; 1130 + struct xarray *xa; 1131 + unsigned long idx; 1132 + 1133 + if (!msi_ctrl_valid(dev, &ctrl)) 1134 + return; 1135 + 1136 + xa = &dev->msi.data->__domains[ctrl.domid].store; 1137 + xa_for_each_range(xa, idx, desc, ctrl.first, ctrl.last) 1138 + desc->irq = 0; 1118 1139 } 1119 1140 1120 1141 /*