Skip to content

Commit 4e9c542

Browse files
committed
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()
2 parents 1a90673 + 0fb7fb7 commit 4e9c542

File tree

7 files changed

+44
-15
lines changed

7 files changed

+44
-15
lines changed

drivers/base/platform-msi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int vir
324324
struct platform_msi_priv_data *data = domain->host_data;
325325

326326
msi_lock_descs(data->dev);
327+
msi_domain_depopulate_descs(data->dev, virq, nr_irqs);
327328
irq_domain_free_irqs_common(domain, virq, nr_irqs);
328329
msi_free_msi_descs_range(data->dev, virq, virq + nr_irqs - 1);
329330
msi_unlock_descs(data->dev);

drivers/pci/msi/api.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,11 @@ EXPORT_SYMBOL_GPL(pci_msix_alloc_irq_at);
163163

164164
/**
165165
* pci_msix_free_irq - Free an interrupt on a PCI/MSIX interrupt domain
166-
* which was allocated via pci_msix_alloc_irq_at()
167166
*
168167
* @dev: The PCI device to operate on
169168
* @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.
171171
*/
172172
void pci_msix_free_irq(struct pci_dev *dev, struct msi_map map)
173173
{

include/linux/msi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,8 @@ int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
635635
int nvec, msi_alloc_info_t *args);
636636
int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
637637
int virq, int nvec, msi_alloc_info_t *args);
638+
void msi_domain_depopulate_descs(struct device *dev, int virq, int nvec);
639+
638640
struct irq_domain *
639641
__platform_msi_create_device_domain(struct device *dev,
640642
unsigned int nvec,

kernel/irq/ipi.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,9 @@ EXPORT_SYMBOL_GPL(ipi_get_hwirq);
188188
static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data,
189189
const struct cpumask *dest, unsigned int cpu)
190190
{
191-
const struct cpumask *ipimask = irq_data_get_affinity_mask(data);
191+
const struct cpumask *ipimask;
192192

193-
if (!chip || !ipimask)
193+
if (!chip || !data)
194194
return -EINVAL;
195195

196196
if (!chip->ipi_send_single && !chip->ipi_send_mask)
@@ -199,6 +199,10 @@ static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data,
199199
if (cpu >= nr_cpu_ids)
200200
return -EINVAL;
201201

202+
ipimask = irq_data_get_affinity_mask(data);
203+
if (!ipimask)
204+
return -EINVAL;
205+
202206
if (dest) {
203207
if (!cpumask_subset(dest, ipimask))
204208
return -EINVAL;

kernel/irq/irqdesc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ static struct attribute *irq_attrs[] = {
277277
};
278278
ATTRIBUTE_GROUPS(irq);
279279

280-
static struct kobj_type irq_kobj_type = {
280+
static const struct kobj_type irq_kobj_type = {
281281
.release = irq_kobj_release,
282282
.sysfs_ops = &kobj_sysfs_ops,
283283
.default_groups = irq_groups,
@@ -335,7 +335,7 @@ postcore_initcall(irq_sysfs_init);
335335

336336
#else /* !CONFIG_SYSFS */
337337

338-
static struct kobj_type irq_kobj_type = {
338+
static const struct kobj_type irq_kobj_type = {
339339
.release = irq_kobj_release,
340340
};
341341

kernel/irq/irqdomain.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,8 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
11471147
domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data);
11481148

11491149
if (domain) {
1150-
domain->root = parent->root;
1150+
if (parent)
1151+
domain->root = parent->root;
11511152
domain->parent = parent;
11521153
domain->flags |= flags;
11531154

kernel/irq/msi.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -830,11 +830,8 @@ static struct irq_domain *__msi_create_irq_domain(struct fwnode_handle *fwnode,
830830
domain = irq_domain_create_hierarchy(parent, flags | IRQ_DOMAIN_FLAG_MSI, 0,
831831
fwnode, &msi_domain_ops, info);
832832

833-
if (domain) {
834-
if (!domain->name && info->chip)
835-
domain->name = info->chip->name;
833+
if (domain)
836834
irq_domain_update_bus_token(domain, info->bus_token);
837-
}
838835

839836
return domain;
840837
}
@@ -1084,10 +1081,13 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
10841081
struct xarray *xa;
10851082
int ret, virq;
10861083

1087-
if (!msi_ctrl_valid(dev, &ctrl))
1088-
return -EINVAL;
1089-
10901084
msi_lock_descs(dev);
1085+
1086+
if (!msi_ctrl_valid(dev, &ctrl)) {
1087+
ret = -EINVAL;
1088+
goto unlock;
1089+
}
1090+
10911091
ret = msi_domain_add_simple_msi_descs(dev, &ctrl);
10921092
if (ret)
10931093
goto unlock;
@@ -1109,14 +1109,35 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
11091109
return 0;
11101110

11111111
fail:
1112-
for (--virq; virq >= virq_base; virq--)
1112+
for (--virq; virq >= virq_base; virq--) {
1113+
msi_domain_depopulate_descs(dev, virq, 1);
11131114
irq_domain_free_irqs_common(domain, virq, 1);
1115+
}
11141116
msi_domain_free_descs(dev, &ctrl);
11151117
unlock:
11161118
msi_unlock_descs(dev);
11171119
return ret;
11181120
}
11191121

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;
1139+
}
1140+
11201141
/*
11211142
* Carefully check whether the device can use reservation mode. If
11221143
* reservation mode is enabled then the early activation will assign a

0 commit comments

Comments
 (0)