[GIT,pull] irq/urgent for v6.3-rc1
Commit Message
Linus,
please pull the latest irq/urgent branch from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-2023-03-05
up to: 0fb7fb713461: genirq/msi, platform-msi: Ensure that MSI descriptors are unreferenced
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.
Thanks,
tglx
------------------>
Johan Hovold (21):
genirq/msi: Drop dead domain name assignment
Juergen Gross (1):
irqdomain: Add missing NULL pointer check in irq_domain_create_hierarchy()
Marc Zyngier (4):
genirq/msi: Take the per-device MSI lock before validating the control structure
Reinette Chatre (1):
PCI/MSI: Clarify usage of pci_msix_free_irq()
Sergey Shtylyov (1):
genirq/ipi: Fix NULL pointer deref in irq_data_get_affinity_mask()
Thomas Gleixner (1):
genirq/msi, platform-msi: Ensure that MSI descriptors are unreferenced
Thomas Weißschuh (1):
genirq/irqdesc: Make kobj_type structures constant
drivers/base/platform-msi.c | 1 +
drivers/pci/msi/api.c | 4 ++--
include/linux/msi.h | 2 ++
kernel/irq/ipi.c | 8 ++++++--
kernel/irq/irqdesc.c | 4 ++--
kernel/irq/irqdomain.c | 3 ++-
kernel/irq/msi.c | 28 +++++++++++++++++++++++-----
kernel/irq/msi.c | 9 ++++++---
8 files changed, 44 insertions(+), 15 deletions(-)
Comments
On Sun, Mar 5, 2023 at 12:55 AM Thomas Gleixner <tglx@linutronix.de> wrote:
>
> ...
> kernel/irq/msi.c | 28 +++++++++++++++++++++++-----
> kernel/irq/msi.c | 9 ++++++---
> 8 files changed, 44 insertions(+), 15 deletions(-)
Funky diffstat you have there, with the same file done twice. I get
(and would have expected)
...
kernel/irq/msi.c | 37 +++++++++++++++++++++++++++++--------
7 files changed, 44 insertions(+), 15 deletions(-)
instead.
Linus
The pull request you sent on Sun, 5 Mar 2023 09:54:57 +0100 (CET):
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-2023-03-05
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/4e9c542c7a51bcc8f6ce283459900ba47a6690f5
Thank you!
On Sun, Mar 05 2023 at 11:24, Linus Torvalds wrote:
> On Sun, Mar 5, 2023 at 12:55 AM Thomas Gleixner <tglx@linutronix.de> wrote:
>> ...
>> kernel/irq/msi.c | 28 +++++++++++++++++++++++-----
>> kernel/irq/msi.c | 9 ++++++---
>> 8 files changed, 44 insertions(+), 15 deletions(-)
>
> Funky diffstat you have there, with the same file done twice. I get
> (and would have expected)
Hrm.
> ...
> kernel/irq/msi.c | 37 +++++++++++++++++++++++++++++--------
> 7 files changed, 44 insertions(+), 15 deletions(-)
>
> instead.
That looks more correct. Let me see what my script zoo managed to get
wrong this time.
Thanks,
tglx
On Sun, Mar 5, 2023 at 11:47 AM Thomas Gleixner <tglx@linutronix.de> wrote:
>
> That looks more correct. Let me see what my script zoo managed to get
> wrong this time.
I think your scripts did the equivalent of generating the diffs for
all commits separately, and then feeding that to "diffstat".
That _is_ a kind of real diffstat too.
It's just not the one I get when I pull and compare (since I'll be
using the "end result" diff, not the "commits as separate diffs" one).
Linus
On Sun, Mar 05 2023 at 11:50, Linus Torvalds wrote:
> On Sun, Mar 5, 2023 at 11:47 AM Thomas Gleixner <tglx@linutronix.de> wrote:
>>
>> That looks more correct. Let me see what my script zoo managed to get
>> wrong this time.
>
> I think your scripts did the equivalent of generating the diffs for
> all commits separately, and then feeding that to "diffstat".
Kinda. It's the case where the merge in the middle of the commits caused
the thing to create something completely nonsensical. There is even a
comment which says:
# FIXME: Merge into Linus head and diff there
I put that in after you explained it to me quite some years ago that in
that case 'git merge-base irq/urgent linus' does not work.
Obviously that lazy sod who put the comment there did never bother to
fix it for real. :)
Thanks,
tglx
@@ -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);
@@ -631,6 +631,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,
@@ -1172,7 +1172,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;
}
@@ -1112,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
@@ -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)
{
@@ -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,
};
@@ -1084,10 +1084,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;