From: sashiko-bot@kernel.org
To: "Marek Vasut" <marek.vasut+renesas@mailbox.org>,
linux-pci@vger.kernel.org
Cc: wsa+renesas@sang-engineering.com
Subject: Re: [PATCH 1/2] PCI: dwc: rcar-gen4: Replace pe_rst GPIO PERST with GPIO reset aux driver
Date: Wed, 28 Oct 2026 17:35:47 +0000 [thread overview]
Message-ID: <sashiko-outbox-188239@kernel.org> (raw)
In-Reply-To: <20261028172133.20903-1-marek.vasut+renesas@mailbox.org>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] PCI: dwc: rcar-gen4: broken error handling in rcar_gen4_pcie_host_perst_get()
- [High] PCI: dwc: rcar-gen4: rcar->perst UAF across suspend/resume in host_deinit()
- [Medium] PCI: dwc: Kconfig: PCIE_RCAR_GEN4_HOST selects RESET_GPIO without dependencies
--
commit 5d439d30a4d77a2c89c803394ba82b6874d3a0c5
Author: Marek Vasut <marek.vasut+renesas@mailbox.org>
PCI: dwc: rcar-gen4: Replace pe_rst GPIO PERST with GPIO reset aux driver
This commit removes the pe_rst GPIO descriptor from the DesignWare PCIe core
and switches the R-Car Gen4 PCIe host driver to acquire PERST# as a reset
control via the reset-gpio auxiliary driver or from a root port subnode in
rcar_gen4_pcie_host_init().
> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> index 0a0d56fcf0ac9..d65cf1e9d842b 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -350,6 +350,7 @@ config PCIE_RCAR_GEN4_HOST
> depends on PCI_MSI
> select PCIE_DW_HOST
> select PCIE_RCAR_GEN4
> + select RESET_GPIO
[Severity: Medium]
In drivers/reset/Kconfig, RESET_GPIO is guarded by if RESET_CONTROLLER and
has depends on GPIOLIB:
drivers/reset/Kconfig:
if RESET_CONTROLLER
...
config RESET_GPIO
tristate "GPIO reset controller"
depends on GPIOLIB
select AUXILIARY_BUS
Since PCIE_RCAR_GEN4_HOST only depends on ARM64 && (ARCH_RENESAS ||
COMPILE_TEST) and PCI_MSI, can selecting RESET_GPIO here trigger Kconfig
unmet direct dependency warnings and build failures when RESET_CONTROLLER=n
or GPIOLIB=n (for example with COMPILE_TEST=y)?
> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index fceecbd16355c..d3bf01485e11d 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
[ ... ]
> @@ -594,19 +583,84 @@ static int rcar_gen4_pcie_enable_device(struct pci_host_bridge *bridge,
> return 0;
> }
>
> +static int rcar_gen4_pcie_host_perst_get(struct dw_pcie *dw)
> +{
> + struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
> + struct device_node *root_port;
> + struct device *dev = dw->dev;
> + struct reset_control *perst;
> + int index;
[ ... ]
> + index = reset_control_get_count(dev);
> + if (index < 0)
> + return index;
> +
> + /* Attempt to request GPIO PERST# in PCIe controller node. */
> + perst = of_reset_control_get_exclusive_by_index(dev->of_node, index);
> + if (!IS_ERR(perst))
> + goto exit;
> +
> + /* No GPIO reset, test for root port subnode. */
> + root_port = of_get_next_available_child(dev->of_node, NULL);
> + if (!root_port)
> + return dev_err_probe(dev, -EINVAL, "Failed to get PERST# in root port\n");
> +
> + /* Attempt to request reset controller PERST# in root port subnode. */
> + perst = of_reset_control_get_optional_exclusive(root_port, "perst");
> + of_node_put(root_port);
> + if (IS_ERR(perst))
> + return dev_err_probe(dev, PTR_ERR(perst), "Failed to get PERST#\n");
[Severity: High]
What happens in rcar_gen4_pcie_host_perst_get() when reset-gpios is present
in dev->of_node, but of_reset_control_get_exclusive_by_index() returns
ERR_PTR(-EPROBE_DEFER) because the GPIO provider or the reset-gpio auxiliary
driver has not bound yet?
In drivers/reset/core.c:__fwnode_reset_control_get(), if reset-gpios is
present in the node, __reset_add_reset_gpio_device() or __reset_find_rcdev()
returns -EPROBE_DEFER until the GPIO device and the reset.gpio auxiliary
device are ready.
Because rcar_gen4_pcie_host_perst_get() does not check whether PTR_ERR(perst)
is something other than -ENOENT before falling through to the root_port
lookup:
1. On R-Car V4H boards (such as r8a779g0.dtsi with White Hawk or Sparrow
Hawk), the controller node has a pci@0,0 child node without a "perst" reset
property while reset-gpios is in the controller node. Falling through on
-EPROBE_DEFER causes of_reset_control_get_optional_exclusive(root_port,
"perst") to return NULL, so rcar->perst is set to NULL and probe succeeds
without acquiring or deasserting the GPIO PERST#.
2. On R-Car S4 and V4M boards (such as r8a779f0.dtsi Spider and r8a779h0.dtsi
Gray Hawk), there is no root port child node, so falling through on
-EPROBE_DEFER hits if (!root_port) and fails probe permanently with -EINVAL
instead of deferring.
3. Since reset-gpios is optional according to the binding and commit
description, if a controller node has neither reset-gpios nor a root port
child node, of_reset_control_get_exclusive_by_index() returns ERR_PTR(-ENOENT)
and if (!root_port) now fails probe with -EINVAL instead of treating PERST# as
optional.
Should this check for PTR_ERR(perst) != -ENOENT after
of_reset_control_get_exclusive_by_index(), and allow a missing root_port when
PTR_ERR(perst) == -ENOENT?
[ ... ]
> @@ -616,6 +670,10 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
> struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
> int ret;
>
> + ret = rcar_gen4_pcie_host_perst_get(dw);
> + if (ret)
> + return ret;
> +
> if (pp->bridge)
> pp->bridge->enable_device = rcar_gen4_pcie_enable_device;
>
> @@ -623,7 +681,7 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
>
> ret = rcar->drvdata->init(rcar);
> if (ret)
> - return ret;
> + goto err_init;
>
> /*
> * According to the section 3.5.7.2 "RC Mode" in DWC PCIe Dual Mode
> @@ -646,6 +704,8 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
>
> err:
> rcar->drvdata->deinit(rcar);
> +err_init:
> + reset_control_put(rcar->perst);
> return ret;
> }
>
> @@ -656,6 +716,7 @@ static void rcar_gen4_pcie_host_deinit(struct dw_pcie_rp *pp)
>
> rcar_gen4_pcie_host_perst_assert(pp, true);
> rcar->drvdata->deinit(rcar);
> + reset_control_put(rcar->perst);
> }
[Severity: High]
Can moving rcar_gen4_pcie_host_perst_get() and reset_control_put(rcar->perst)
into the dw_pcie_host_ops .init and .deinit callbacks cause a use-after-free
and double-free of rcar->perst across system suspend/resume followed by
driver removal?
In drivers/pci/controller/dwc/pcie-designware-host.c, the .deinit and .init
callbacks are also invoked during noirq suspend and resume:
dw_pcie_suspend_noirq()
pci->pp.ops->deinit(&pci->pp)
rcar_gen4_pcie_host_deinit()
reset_control_put(rcar->perst);
dw_pcie_resume_noirq()
pci->pp.ops->init(&pci->pp)
rcar_gen4_pcie_host_init()
...
err_deinit:
pci->pp.ops->deinit(&pci->pp)
rcar_gen4_pcie_host_deinit()
reset_control_put(rcar->perst);
When dw_pcie_suspend_noirq() runs, rcar_gen4_pcie_host_deinit() frees
rcar->perst via reset_control_put() while leaving the dangling pointer in
rcar->perst.
If the device is later unbound while suspended, or if dw_pcie_resume_noirq()
fails (either inside rcar_gen4_pcie_host_init() or at err_deinit: when link
training times out in dw_pcie_wait_for_link()), a subsequent
rcar_gen4_pcie_remove() -> dw_pcie_host_deinit() ->
rcar_gen4_pcie_host_deinit() will call reset_control_assert(rcar->perst) and
reset_control_put(rcar->perst) on the already-freed rcar->perst pointer.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028172133.20903-1-marek.vasut+renesas@mailbox.org?part=1
prev parent reply other threads:[~2026-10-28 17:35 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 17:21 [PATCH 1/2] PCI: dwc: rcar-gen4: Replace pe_rst GPIO PERST with GPIO reset aux driver Marek Vasut
2026-10-28 17:21 ` [PATCH 2/2] PCI: rcar-gen4: Inline rcar_gen4_pcie_host_perst_assert() again Marek Vasut
2026-10-28 17:32 ` sashiko-bot
2026-10-28 17:27 ` [PATCH 1/2] PCI: dwc: rcar-gen4: Replace pe_rst GPIO PERST with GPIO reset aux driver Marek Vasut
2026-10-29 13:52 ` Andy Shevchenko
2026-10-29 16:19 ` Marek Vasut
2026-10-28 17:35 ` sashiko-bot [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=sashiko-outbox-188239@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=marek.vasut+renesas@mailbox.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=wsa+renesas@sang-engineering.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.