From: Fuad Tabba <fuad.tabba@linux.dev>
To: Rob Herring <robh@kernel.org>, Saravana Kannan <saravanak@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>,
Frank Li <Frank.Li@nxp.com>,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Fuad Tabba <tabba@google.com>
Subject: [PATCH v2 2/2] of/irq: Stop the MSI walk at the first msi-parent
Date: Mon, 7 Sep 2026 12:29:44 +0100 [thread overview]
Message-ID: <20260907112944.313618-3-fuad.tabba@linux.dev> (raw)
In-Reply-To: <20260907112944.313618-1-fuad.tabba@linux.dev>
of_check_msi_parent() returns -EINVAL both when the msi-parent names a
controller other than the one the caller filters on and when #msi-cells
isn't 0, so of_msi_xlate() can't tell the two apart and carries on up
the hierarchy. An ancestor's msi-map then maps the device onto a
controller its own node didn't name.
Hand the parsed specifier back to of_msi_xlate(), which owns the
reference as it already does on the msi-map path, and end the walk at
any node that declares an msi-parent.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260904074800.875391F00A3F@smtp.kernel.org/
Suggested-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Link: https://lore.kernel.org/all/apqnaNmeuUjfC8Ng@red-moon/
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
drivers/of/irq.c | 39 ++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 109c54f346479..4fbbd13f4d0a8 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -765,34 +765,27 @@ void __init of_irq_init(const struct of_device_id *matches)
}
}
-static int of_check_msi_parent(struct device_node *dev_node, struct device_node **msi_node)
+static int of_check_msi_parent(struct device_node *dev_node, struct device_node **msi_node,
+ struct of_phandle_args *msi_spec)
{
- struct of_phandle_args msi_spec;
int ret;
/*
* An msi-parent phandle with a missing or == 0 #msi-cells
* property identifies a 1:1 ID translation mapping.
*
- * Set the msi controller node if the firmware matches this
- * condition.
+ * @msi_spec keeps a reference to the target node whenever the
+ * phandle parses, -EINVAL included, and the caller releases it.
*/
ret = of_parse_phandle_with_optional_args(dev_node, "msi-parent", "#msi-cells",
- 0, &msi_spec);
+ 0, msi_spec);
if (ret)
return ret;
- if ((*msi_node && *msi_node != msi_spec.np) || msi_spec.args_count != 0)
- ret = -EINVAL;
+ if ((*msi_node && *msi_node != msi_spec->np) || msi_spec->args_count != 0)
+ return -EINVAL;
- if (!ret && !*msi_node) {
- /* Return with a node reference held */
- *msi_node = msi_spec.np;
- return 0;
- }
- of_node_put(msi_spec.np);
-
- return ret;
+ return 0;
}
/**
@@ -806,7 +799,9 @@ static int of_check_msi_parent(struct device_node *dev_node, struct device_node
* @id_in: Device ID.
*
* Walk up the device hierarchy looking for devices with a "msi-map"
- * or "msi-parent" property. If found, apply the mapping to @id_in.
+ * or "msi-parent" property. If found, apply the mapping to @id_in. With
+ * @msi_np non-NULL, a device declaring an msi-parent ends the walk, usable
+ * or not.
*
* Returns: The mapped MSI id.
*/
@@ -821,6 +816,7 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
*/
for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
struct of_phandle_args msi_spec = {};
+ int ret;
if (!of_map_msi_id(parent_dev->of_node, id_in, msi_np, &msi_spec)) {
if (msi_spec.np) {
@@ -835,8 +831,17 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
break;
}
/* -ENODEV: msi-map absent → check for msi-parent */
- if (msi_np && !of_check_msi_parent(parent_dev->of_node, msi_np))
+ if (!msi_np)
+ continue;
+
+ ret = of_check_msi_parent(parent_dev->of_node, msi_np, &msi_spec);
+ if (msi_spec.np) {
+ /* A declared msi-parent names the controller, usable or not */
+ if (!ret && !*msi_np)
+ *msi_np = of_node_get(msi_spec.np);
+ of_node_put(msi_spec.np);
break;
+ }
}
return id_out;
}
--
2.39.5
prev parent reply other threads:[~2026-09-07 11:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 11:29 [PATCH v2 0/2] of/irq: msi-parent handling in of_msi_xlate() Fuad Tabba
2026-09-07 11:29 ` [PATCH v2 1/2] of/irq: Fix device node refcount leak in of_check_msi_parent() Fuad Tabba
2026-09-07 11:45 ` sashiko-bot
2026-09-07 11:59 ` Fuad Tabba
2026-09-07 11:29 ` Fuad Tabba [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260907112944.313618-3-fuad.tabba@linux.dev \
--to=fuad.tabba@linux.dev \
--cc=Frank.Li@nxp.com \
--cc=devicetree@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=robh@kernel.org \
--cc=saravanak@kernel.org \
--cc=tabba@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.