mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 14:14:24 +08:00
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. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmQEVToTHHRnbHhAbGlu dXRyb25peC5kZQAKCRCmGPVMDXSYodc9EACg5HBOGsh5OV8pwnuEDqfThK/dOZ5k LJ8xQjGAx29JeNWu4gkkHaSDEGjZhwLiZlB6qUeH+LPQ1NgmAlLL3T2NxEOOWa6y z/xQv+1Ceu6XxazpCSFRWR/6w4Nyup92jhlsUIkmmsWkVvKH/pV6Uo+3ta0WagWg heb3vqts6J0AOJaMepF8azYGbwAPSIElNLI1UtiEuQYEKU55N8jLK20VJTL6lzJ2 FyRg/0ghNWDAaBdnv4cZCQ/MzoG5UkoU3f2cqhdSce5mqnq2fKRfgBjzllNgaRgA zxOxIR88QaKTMHIr+WKD1dyWxDQlotFbBOkmVW39XAa13rn42s4GIeW88VCjJGww RAm52SbC48cCIyNQlh4A6Vhb4vjPx2DndWbWnnVj5fWlUevdAPRxSlm4BjfxFxe+ LbuZCRRL1jjlC0fXmhVXTTxeE1/K7jarAZwRV7Nxhr3g0gT+Zv1jyaaW9rWuHq5U 3pS+xBl89LA/VYp9tv6jDfJlocmRwgrFbGX4UlfikqtObdTFqcH0FtmqisE61fZS n0194BMWNDfPSibSpDohf/CDPoHZ6pNxeuqkVDiisUJHPpIYOt8+lH+8//DgBL7a oi9zS0JazPIn2VM6NB4f/WXOYmS9GZq5+loiYEWb52AYtodKUKmOoWG0SUyy6XFr E7yJzemsUwrJVg== =jWot -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
4e9c542c7a
@ -324,6 +324,7 @@ void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int vir
|
||||
struct platform_msi_priv_data *data = domain->host_data;
|
||||
|
||||
msi_lock_descs(data->dev);
|
||||
msi_domain_depopulate_descs(data->dev, virq, nr_irqs);
|
||||
irq_domain_free_irqs_common(domain, virq, nr_irqs);
|
||||
msi_free_msi_descs_range(data->dev, virq, virq + nr_irqs - 1);
|
||||
msi_unlock_descs(data->dev);
|
||||
|
@ -163,11 +163,11 @@ EXPORT_SYMBOL_GPL(pci_msix_alloc_irq_at);
|
||||
|
||||
/**
|
||||
* pci_msix_free_irq - Free an interrupt on a PCI/MSIX interrupt domain
|
||||
* which was allocated via pci_msix_alloc_irq_at()
|
||||
*
|
||||
* @dev: The PCI device to operate on
|
||||
* @map: A struct msi_map describing the interrupt to free
|
||||
* as returned from the allocation function.
|
||||
*
|
||||
* Undo an interrupt vector allocation. Does not disable MSI-X.
|
||||
*/
|
||||
void pci_msix_free_irq(struct pci_dev *dev, struct msi_map map)
|
||||
{
|
||||
|
@ -635,6 +635,8 @@ int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
|
||||
int nvec, msi_alloc_info_t *args);
|
||||
int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
|
||||
int virq, int nvec, msi_alloc_info_t *args);
|
||||
void msi_domain_depopulate_descs(struct device *dev, int virq, int nvec);
|
||||
|
||||
struct irq_domain *
|
||||
__platform_msi_create_device_domain(struct device *dev,
|
||||
unsigned int nvec,
|
||||
|
@ -188,9 +188,9 @@ EXPORT_SYMBOL_GPL(ipi_get_hwirq);
|
||||
static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data,
|
||||
const struct cpumask *dest, unsigned int cpu)
|
||||
{
|
||||
const struct cpumask *ipimask = irq_data_get_affinity_mask(data);
|
||||
const struct cpumask *ipimask;
|
||||
|
||||
if (!chip || !ipimask)
|
||||
if (!chip || !data)
|
||||
return -EINVAL;
|
||||
|
||||
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,
|
||||
if (cpu >= nr_cpu_ids)
|
||||
return -EINVAL;
|
||||
|
||||
ipimask = irq_data_get_affinity_mask(data);
|
||||
if (!ipimask)
|
||||
return -EINVAL;
|
||||
|
||||
if (dest) {
|
||||
if (!cpumask_subset(dest, ipimask))
|
||||
return -EINVAL;
|
||||
|
@ -277,7 +277,7 @@ static struct attribute *irq_attrs[] = {
|
||||
};
|
||||
ATTRIBUTE_GROUPS(irq);
|
||||
|
||||
static struct kobj_type irq_kobj_type = {
|
||||
static const struct kobj_type irq_kobj_type = {
|
||||
.release = irq_kobj_release,
|
||||
.sysfs_ops = &kobj_sysfs_ops,
|
||||
.default_groups = irq_groups,
|
||||
@ -335,7 +335,7 @@ postcore_initcall(irq_sysfs_init);
|
||||
|
||||
#else /* !CONFIG_SYSFS */
|
||||
|
||||
static struct kobj_type irq_kobj_type = {
|
||||
static const struct kobj_type irq_kobj_type = {
|
||||
.release = irq_kobj_release,
|
||||
};
|
||||
|
||||
|
@ -1147,7 +1147,8 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
|
||||
domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data);
|
||||
|
||||
if (domain) {
|
||||
domain->root = parent->root;
|
||||
if (parent)
|
||||
domain->root = parent->root;
|
||||
domain->parent = parent;
|
||||
domain->flags |= flags;
|
||||
|
||||
|
@ -830,11 +830,8 @@ static struct irq_domain *__msi_create_irq_domain(struct fwnode_handle *fwnode,
|
||||
domain = irq_domain_create_hierarchy(parent, flags | IRQ_DOMAIN_FLAG_MSI, 0,
|
||||
fwnode, &msi_domain_ops, info);
|
||||
|
||||
if (domain) {
|
||||
if (!domain->name && info->chip)
|
||||
domain->name = info->chip->name;
|
||||
if (domain)
|
||||
irq_domain_update_bus_token(domain, info->bus_token);
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
@ -1084,10 +1081,13 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
|
||||
struct xarray *xa;
|
||||
int ret, virq;
|
||||
|
||||
if (!msi_ctrl_valid(dev, &ctrl))
|
||||
return -EINVAL;
|
||||
|
||||
msi_lock_descs(dev);
|
||||
|
||||
if (!msi_ctrl_valid(dev, &ctrl)) {
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ret = msi_domain_add_simple_msi_descs(dev, &ctrl);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
@ -1109,14 +1109,35 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
for (--virq; virq >= virq_base; virq--)
|
||||
for (--virq; virq >= virq_base; virq--) {
|
||||
msi_domain_depopulate_descs(dev, virq, 1);
|
||||
irq_domain_free_irqs_common(domain, virq, 1);
|
||||
}
|
||||
msi_domain_free_descs(dev, &ctrl);
|
||||
unlock:
|
||||
msi_unlock_descs(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void msi_domain_depopulate_descs(struct device *dev, int virq_base, int nvec)
|
||||
{
|
||||
struct msi_ctrl ctrl = {
|
||||
.domid = MSI_DEFAULT_DOMAIN,
|
||||
.first = virq_base,
|
||||
.last = virq_base + nvec - 1,
|
||||
};
|
||||
struct msi_desc *desc;
|
||||
struct xarray *xa;
|
||||
unsigned long idx;
|
||||
|
||||
if (!msi_ctrl_valid(dev, &ctrl))
|
||||
return;
|
||||
|
||||
xa = &dev->msi.data->__domains[ctrl.domid].store;
|
||||
xa_for_each_range(xa, idx, desc, ctrl.first, ctrl.last)
|
||||
desc->irq = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Carefully check whether the device can use reservation mode. If
|
||||
* reservation mode is enabled then the early activation will assign a
|
||||
|
Loading…
Reference in New Issue
Block a user