* [PATCH v5 1/5] phy: qcom: qmp-combo: Prevent unnecessary PM runtime suspend at boot
2026-07-21 13:05 [PATCH v5 0/5] phy: qcom: Fix possible NULL-deref and runtime PM race conditions Loic Poulain
@ 2026-07-21 13:05 ` Loic Poulain
2026-07-21 13:05 ` [PATCH v5 2/5] phy: qcom: qmp-usbc: " Loic Poulain
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Loic Poulain @ 2026-07-21 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Dmitry Baryshkov, Wesley Cheng
Cc: linux-arm-msm, linux-phy, linux-kernel, Dmitry Baryshkov,
Abel Vesa, Konrad Dybcio, Loic Poulain
Runtime PM has to be enabled before creating the PHYs, since phy_create()
only enables runtime PM on the PHY devices if it is already enabled on
this parent device. This opens a small window where the device can be
runtime suspended after pm_runtime_enable() and before the later
pm_runtime_forbid(), causing an unnecessary suspend/resume cycle while
the PHYs are not yet registered.
Take a runtime PM usage reference with pm_runtime_get_noresume() before
enabling runtime PM and release it once the PHYs have been created to
prevent the device from being runtime suspended during that window.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index cdcfad2e86b1d37650c4d7b0433319837ee9c9d4..affc8e040bb968a5b9d0b6f6fc2694c471368729 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -4934,10 +4934,16 @@ static int qmp_combo_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ /*
+ * Enable runtime PM before creating the PHYs, phy_create() only enables
+ * it on the PHY devices if already enabled on the parent. Hold a usage
+ * reference so callbacks cannot run until the PHY is ready.
+ */
+ pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
- goto err_node_put;
+ goto err_pm_put;
/*
* Prevent runtime pm from being ON by default. Users can enable
* it using power/control in sysfs.
@@ -4946,14 +4952,13 @@ static int qmp_combo_probe(struct platform_device *pdev)
ret = qmp_combo_register_clocks(qmp, usb_np, dp_np);
if (ret)
- goto err_node_put;
-
+ goto err_pm_put;
qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops);
if (IS_ERR(qmp->usb_phy)) {
ret = PTR_ERR(qmp->usb_phy);
dev_err(dev, "failed to create USB PHY: %d\n", ret);
- goto err_node_put;
+ goto err_pm_put;
}
phy_set_drvdata(qmp->usb_phy, qmp);
@@ -4962,11 +4967,13 @@ static int qmp_combo_probe(struct platform_device *pdev)
if (IS_ERR(qmp->dp_phy)) {
ret = PTR_ERR(qmp->dp_phy);
dev_err(dev, "failed to create DP PHY: %d\n", ret);
- goto err_node_put;
+ goto err_pm_put;
}
phy_set_drvdata(qmp->dp_phy, qmp);
+ pm_runtime_put(dev);
+
if (usb_np == dev->of_node)
phy_provider = devm_of_phy_provider_register(dev, qmp_combo_phy_xlate);
else
@@ -4977,6 +4984,8 @@ static int qmp_combo_probe(struct platform_device *pdev)
return PTR_ERR_OR_ZERO(phy_provider);
+err_pm_put:
+ pm_runtime_put_noidle(dev);
err_node_put:
of_node_put(usb_np);
of_node_put(dp_np);
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v5 2/5] phy: qcom: qmp-usbc: Prevent unnecessary PM runtime suspend at boot
2026-07-21 13:05 [PATCH v5 0/5] phy: qcom: Fix possible NULL-deref and runtime PM race conditions Loic Poulain
2026-07-21 13:05 ` [PATCH v5 1/5] phy: qcom: qmp-combo: Prevent unnecessary PM runtime suspend at boot Loic Poulain
@ 2026-07-21 13:05 ` Loic Poulain
2026-07-21 13:13 ` sashiko-bot
2026-07-21 13:32 ` Dmitry Baryshkov
2026-07-21 13:05 ` [PATCH v5 3/5] phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime suspend Loic Poulain
` (2 subsequent siblings)
4 siblings, 2 replies; 10+ messages in thread
From: Loic Poulain @ 2026-07-21 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Dmitry Baryshkov, Wesley Cheng
Cc: linux-arm-msm, linux-phy, linux-kernel, Konrad Dybcio, Abel Vesa,
Dmitry Baryshkov, Loic Poulain
Runtime PM has to be enabled before creating the PHYs, since phy_create()
only enables runtime PM on the PHY devices if it is already enabled on
this parent device. This opens a small window where the device can be
runtime suspended after pm_runtime_enable() and before the later
pm_runtime_forbid(), causing an unnecessary suspend/resume cycle while
the PHYs are not yet registered.
Take a runtime PM usage reference with pm_runtime_get_noresume() before
enabling runtime PM and release it once the PHYs have been created to
prevent the device from being runtime suspended during that window.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index ab3055bb5b0c198832ae06dfcd04fd34395e271d..4317224070fd8dec98090e9200ac7d0e97265979 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -1959,10 +1959,16 @@ static int qmp_usbc_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ /*
+ * Enable runtime PM before creating the PHYs, phy_create() only enables
+ * it on the PHY devices if already enabled on the parent. Hold a usage
+ * reference so callbacks cannot run until the PHY is ready.
+ */
+ pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
- goto err_node_put;
+ goto err_pm_put;
/*
* Prevent runtime pm from being ON by default. Users can enable
* it using power/control in sysfs.
@@ -1971,13 +1977,13 @@ static int qmp_usbc_probe(struct platform_device *pdev)
ret = qmp_usbc_register_clocks(qmp, np);
if (ret)
- goto err_node_put;
+ goto err_pm_put;
qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
if (IS_ERR(qmp->usb_phy)) {
ret = PTR_ERR(qmp->usb_phy);
dev_err(dev, "failed to create PHY: %d\n", ret);
- goto err_node_put;
+ goto err_pm_put;
}
phy_set_drvdata(qmp->usb_phy, qmp);
@@ -1987,17 +1993,21 @@ static int qmp_usbc_probe(struct platform_device *pdev)
if (IS_ERR(qmp->dp_phy)) {
ret = PTR_ERR(qmp->dp_phy);
dev_err(dev, "failed to create PHY: %d\n", ret);
- goto err_node_put;
+ goto err_pm_put;
}
phy_set_drvdata(qmp->dp_phy, qmp);
}
+ pm_runtime_put(dev);
+
of_node_put(np);
phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
+err_pm_put:
+ pm_runtime_put_noidle(dev);
err_node_put:
of_node_put(np);
return ret;
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v5 2/5] phy: qcom: qmp-usbc: Prevent unnecessary PM runtime suspend at boot
2026-07-21 13:05 ` [PATCH v5 2/5] phy: qcom: qmp-usbc: " Loic Poulain
@ 2026-07-21 13:13 ` sashiko-bot
2026-07-21 13:32 ` Dmitry Baryshkov
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-21 13:13 UTC (permalink / raw)
To: Loic Poulain; +Cc: vkoul, linux-phy, neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Asynchronous pm_runtime_put() before devm_of_phy_provider_register() can cause an async suspend race if registration fails.
--
--- Patch [2]: [PATCH v5 2/5] phy: qcom: qmp-usbc: Prevent unnecessary PM runtime suspend at boot ---
commit 4e67cff2d4e3ab76976662b7c3a8f55faa25f2bd
Author: Loic Poulain <loic.poulain@oss.qualcomm.com>
phy: qcom: qmp-usbc: Prevent unnecessary PM runtime suspend at boot
This commit takes a runtime PM usage reference with pm_runtime_get_noresume()
before enabling runtime PM. It then releases the reference once the PHYs
have been created to prevent the device from being runtime suspended during
the creation window.
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index ab3055bb5b0c1..4317224070fd8 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
[ ... ]
> @@ -1987,17 +1993,21 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> if (IS_ERR(qmp->dp_phy)) {
> ret = PTR_ERR(qmp->dp_phy);
> dev_err(dev, "failed to create PHY: %d\n", ret);
> - goto err_node_put;
> + goto err_pm_put;
> }
> phy_set_drvdata(qmp->dp_phy, qmp);
> }
>
> + pm_runtime_put(dev);
> +
> of_node_put(np);
>
> phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
>
> return PTR_ERR_OR_ZERO(phy_provider);
[Severity: High]
Since pm_runtime_put() queues an asynchronous idle notification, is there a
race condition here if devm_of_phy_provider_register() fails?
If devm_of_phy_provider_register() returns an error, the function returns
immediately and triggers devm unwinding. This unwinding will call
pm_runtime_disable() due to the earlier devm_pm_runtime_enable() call.
If pm_runtime_disable() cancels the pending asynchronous idle/suspend work,
could the hardware be left in an incorrect active power state?
Would it be safer to move devm_of_phy_provider_register() before
pm_runtime_put(dev), and use the err_pm_put label (which safely uses the
synchronous pm_runtime_put_noidle()) if it fails?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721-qcom-usb-phy-fix-null-v5-0-a181e2adbd2d@oss.qualcomm.com?part=2
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v5 2/5] phy: qcom: qmp-usbc: Prevent unnecessary PM runtime suspend at boot
2026-07-21 13:05 ` [PATCH v5 2/5] phy: qcom: qmp-usbc: " Loic Poulain
2026-07-21 13:13 ` sashiko-bot
@ 2026-07-21 13:32 ` Dmitry Baryshkov
2026-07-21 14:22 ` Loic Poulain
1 sibling, 1 reply; 10+ messages in thread
From: Dmitry Baryshkov @ 2026-07-21 13:32 UTC (permalink / raw)
To: Loic Poulain
Cc: Vinod Koul, Neil Armstrong, Dmitry Baryshkov, Wesley Cheng,
linux-arm-msm, linux-phy, linux-kernel, Konrad Dybcio, Abel Vesa
On Tue, Jul 21, 2026 at 03:05:46PM +0200, Loic Poulain wrote:
> Runtime PM has to be enabled before creating the PHYs, since phy_create()
> only enables runtime PM on the PHY devices if it is already enabled on
> this parent device. This opens a small window where the device can be
> runtime suspended after pm_runtime_enable() and before the later
> pm_runtime_forbid(), causing an unnecessary suspend/resume cycle while
> the PHYs are not yet registered.
>
> Take a runtime PM usage reference with pm_runtime_get_noresume() before
> enabling runtime PM and release it once the PHYs have been created to
> prevent the device from being runtime suspended during that window.
>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index ab3055bb5b0c198832ae06dfcd04fd34395e271d..4317224070fd8dec98090e9200ac7d0e97265979 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> @@ -1959,10 +1959,16 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> if (ret)
> goto err_node_put;
>
> + /*
> + * Enable runtime PM before creating the PHYs, phy_create() only enables
> + * it on the PHY devices if already enabled on the parent. Hold a usage
> + * reference so callbacks cannot run until the PHY is ready.
> + */
> + pm_runtime_get_noresume(dev);
> pm_runtime_set_active(dev);
> ret = devm_pm_runtime_enable(dev);
> if (ret)
> - goto err_node_put;
> + goto err_pm_put;
> /*
> * Prevent runtime pm from being ON by default. Users can enable
> * it using power/control in sysfs.
> @@ -1971,13 +1977,13 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>
> ret = qmp_usbc_register_clocks(qmp, np);
> if (ret)
> - goto err_node_put;
> + goto err_pm_put;
>
> qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
> if (IS_ERR(qmp->usb_phy)) {
> ret = PTR_ERR(qmp->usb_phy);
> dev_err(dev, "failed to create PHY: %d\n", ret);
> - goto err_node_put;
> + goto err_pm_put;
> }
>
> phy_set_drvdata(qmp->usb_phy, qmp);
> @@ -1987,17 +1993,21 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> if (IS_ERR(qmp->dp_phy)) {
> ret = PTR_ERR(qmp->dp_phy);
> dev_err(dev, "failed to create PHY: %d\n", ret);
> - goto err_node_put;
> + goto err_pm_put;
> }
> phy_set_drvdata(qmp->dp_phy, qmp);
> }
>
> + pm_runtime_put(dev);
Should be _put_sync() ?
> +
> of_node_put(np);
>
> phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
>
> return PTR_ERR_OR_ZERO(phy_provider);
>
> +err_pm_put:
> + pm_runtime_put_noidle(dev);
Why is it _noidle()?
> err_node_put:
> of_node_put(np);
> return ret;
>
> --
> 2.34.1
>
>
> --
> linux-phy mailing list
> linux-phy@lists.infradead.org
> https://lists.infradead.org/mailman/listinfo/linux-phy
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v5 2/5] phy: qcom: qmp-usbc: Prevent unnecessary PM runtime suspend at boot
2026-07-21 13:32 ` Dmitry Baryshkov
@ 2026-07-21 14:22 ` Loic Poulain
0 siblings, 0 replies; 10+ messages in thread
From: Loic Poulain @ 2026-07-21 14:22 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Vinod Koul, Neil Armstrong, Dmitry Baryshkov, Wesley Cheng,
linux-arm-msm, linux-phy, linux-kernel, Konrad Dybcio, Abel Vesa
Hi Dmitry,
On Tue, Jul 21, 2026 at 3:32 PM Dmitry Baryshkov
<dmitry.baryshkov@oss.qualcomm.com> wrote:
>
> On Tue, Jul 21, 2026 at 03:05:46PM +0200, Loic Poulain wrote:
> > Runtime PM has to be enabled before creating the PHYs, since phy_create()
> > only enables runtime PM on the PHY devices if it is already enabled on
> > this parent device. This opens a small window where the device can be
> > runtime suspended after pm_runtime_enable() and before the later
> > pm_runtime_forbid(), causing an unnecessary suspend/resume cycle while
> > the PHYs are not yet registered.
> >
> > Take a runtime PM usage reference with pm_runtime_get_noresume() before
> > enabling runtime PM and release it once the PHYs have been created to
> > prevent the device from being runtime suspended during that window.
> >
> > Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> > Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> > Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> > ---
> > drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 18 ++++++++++++++----
> > 1 file changed, 14 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> > index ab3055bb5b0c198832ae06dfcd04fd34395e271d..4317224070fd8dec98090e9200ac7d0e97265979 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> > @@ -1959,10 +1959,16 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> > if (ret)
> > goto err_node_put;
> >
> > + /*
> > + * Enable runtime PM before creating the PHYs, phy_create() only enables
> > + * it on the PHY devices if already enabled on the parent. Hold a usage
> > + * reference so callbacks cannot run until the PHY is ready.
> > + */
> > + pm_runtime_get_noresume(dev);
> > pm_runtime_set_active(dev);
> > ret = devm_pm_runtime_enable(dev);
> > if (ret)
> > - goto err_node_put;
> > + goto err_pm_put;
> > /*
> > * Prevent runtime pm from being ON by default. Users can enable
> > * it using power/control in sysfs.
> > @@ -1971,13 +1977,13 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> >
> > ret = qmp_usbc_register_clocks(qmp, np);
> > if (ret)
> > - goto err_node_put;
> > + goto err_pm_put;
> >
> > qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
> > if (IS_ERR(qmp->usb_phy)) {
> > ret = PTR_ERR(qmp->usb_phy);
> > dev_err(dev, "failed to create PHY: %d\n", ret);
> > - goto err_node_put;
> > + goto err_pm_put;
> > }
> >
> > phy_set_drvdata(qmp->usb_phy, qmp);
> > @@ -1987,17 +1993,21 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> > if (IS_ERR(qmp->dp_phy)) {
> > ret = PTR_ERR(qmp->dp_phy);
> > dev_err(dev, "failed to create PHY: %d\n", ret);
> > - goto err_node_put;
> > + goto err_pm_put;
> > }
> > phy_set_drvdata(qmp->dp_phy, qmp);
> > }
> >
> > + pm_runtime_put(dev);
>
> Should be _put_sync() ?
Well, yes for avoiding inconsistent state on error path, but it might
be cleaner to move the async put after
devm_of_phy_provider_register(), once we know the probe has succeeded,
and then rely on put_noidle() for all error paths.
>
> > +
> > of_node_put(np);
> >
> > phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
> >
> > return PTR_ERR_OR_ZERO(phy_provider);
> >
> > +err_pm_put:
> > + pm_runtime_put_noidle(dev);
>
> Why is it _noidle()?
The device starts in the active state (pm_runtime_set_active()). Here,
I use put_noidle() only to balance the PM usage counter while keeping
the device active. This restores the runtime PM state to what it was
before the probe (pm_runtime_get_noresume), allowing the device to be
reprobed from the same state.
>
> > err_node_put:
> > of_node_put(np);
> > return ret;
> >
> > --
> > 2.34.1
> >
> >
> > --
> > linux-phy mailing list
> > linux-phy@lists.infradead.org
> > https://lists.infradead.org/mailman/listinfo/linux-phy
>
> --
> With best wishes
> Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v5 3/5] phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime suspend
2026-07-21 13:05 [PATCH v5 0/5] phy: qcom: Fix possible NULL-deref and runtime PM race conditions Loic Poulain
2026-07-21 13:05 ` [PATCH v5 1/5] phy: qcom: qmp-combo: Prevent unnecessary PM runtime suspend at boot Loic Poulain
2026-07-21 13:05 ` [PATCH v5 2/5] phy: qcom: qmp-usbc: " Loic Poulain
@ 2026-07-21 13:05 ` Loic Poulain
2026-07-21 13:16 ` sashiko-bot
2026-07-21 13:05 ` [PATCH v5 4/5] phy: qcom: qmp-usb-legacy: Prevent unnecessary PM runtime suspend at boot Loic Poulain
2026-07-21 13:05 ` [PATCH v5 5/5] phy: qcom: snps-femto-v2: Fix possible NULL-deref on early runtime suspend Loic Poulain
4 siblings, 1 reply; 10+ messages in thread
From: Loic Poulain @ 2026-07-21 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Dmitry Baryshkov, Wesley Cheng
Cc: linux-arm-msm, linux-phy, linux-kernel, Abel Vesa,
Dmitry Baryshkov, Loic Poulain
There is a small window where the runtime suspend callback may run
after pm_runtime_enable() and before pm_runtime_forbid(). In this
case, a crash occurs because runtime suspend/resume dereferences
qmp->phy pointer, which is not yet initialized:
`if (!qmp->phy->init_count) {`
This can also happen if user re-enables runtime-pm via the sysfs
attribute before qmp phy is initialized.
Similarly to other qcom phy drivers, introduce a qmp->phy_initialized
variable that can be used to avoid relying on the possibly uninitialized
phy pointer.
Fixes: e464a3180a43 ("phy: qcom-qmp-usb: split off the legacy USB+dp_com support")
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index 8bf951b0490cfd811635df8940de1b789e21b46c..fc490589c8e4888770807a60170905a1c7610421 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -542,6 +542,8 @@ struct qmp_usb {
enum phy_mode mode;
+ bool phy_initialized;
+
struct phy *phy;
struct clk_fixed_rate pipe_clk_fixed;
@@ -895,6 +897,7 @@ static int qmp_usb_legacy_power_off(struct phy *phy)
static int qmp_usb_legacy_enable(struct phy *phy)
{
+ struct qmp_usb *qmp = phy_get_drvdata(phy);
int ret;
ret = qmp_usb_legacy_init(phy);
@@ -904,14 +907,19 @@ static int qmp_usb_legacy_enable(struct phy *phy)
ret = qmp_usb_legacy_power_on(phy);
if (ret)
qmp_usb_legacy_exit(phy);
+ else
+ qmp->phy_initialized = true;
return ret;
}
static int qmp_usb_legacy_disable(struct phy *phy)
{
+ struct qmp_usb *qmp = phy_get_drvdata(phy);
int ret;
+ qmp->phy_initialized = false;
+
ret = qmp_usb_legacy_power_off(phy);
if (ret)
return ret;
@@ -988,7 +996,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_suspend(struct device *dev)
dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
- if (!qmp->phy->init_count) {
+ if (!qmp->phy_initialized) {
dev_vdbg(dev, "PHY not initialized, bailing out\n");
return 0;
}
@@ -1009,7 +1017,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_resume(struct device *dev)
dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
- if (!qmp->phy->init_count) {
+ if (!qmp->phy_initialized) {
dev_vdbg(dev, "PHY not initialized, bailing out\n");
return 0;
}
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v5 3/5] phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime suspend
2026-07-21 13:05 ` [PATCH v5 3/5] phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime suspend Loic Poulain
@ 2026-07-21 13:16 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-21 13:16 UTC (permalink / raw)
To: Loic Poulain; +Cc: linux-phy, vkoul, olteanv, neil.armstrong
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Incomplete Fix / Unpatched Vulnerability: The identical NULL pointer dereference fixed by this patch in `phy-qcom-qmp-usb-legacy.c` remains unpatched in `phy-qcom-qmp-usb.c`.
--
--- Patch [3]: [PATCH v5 3/5] phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime suspend ---
commit 10908699bb99258db58b260c0d16ab93fd29f9d2
Author: Loic Poulain <loic.poulain@oss.qualcomm.com>
phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime suspend
This commit introduces a phy_initialized flag to prevent a NULL pointer
dereference in the runtime suspend and resume callbacks. This occurs because
pm_runtime_enable() is called before the phy pointer is fully initialized.
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
> index 8bf951b0490cf..fc490589c8e48 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
[ ... ]
> @@ -988,7 +996,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_suspend(struct device *dev)
>
> dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
>
> - if (!qmp->phy->init_count) {
> + if (!qmp->phy_initialized) {
[Severity: High]
This is a pre-existing issue, but does the same vulnerability still exist
in the sibling driver phy-qcom-qmp-usb.c?
Looking at qmp_usb_probe() in drivers/phy/qualcomm/phy-qcom-qmp-usb.c,
devm_pm_runtime_enable(dev) is called before qmp->phy is allocated via
devm_phy_create(). Similar to the legacy driver, there appears to be a
window where early runtime PM suspend (or unprivileged sysfs access) can
trigger qmp_usb_runtime_suspend() and crash:
drivers/phy/qualcomm/phy-qcom-qmp-usb.c:qmp_usb_runtime_suspend() {
...
if (!qmp->phy->init_count) {
dev_vdbg(dev, "PHY not initialized, bailing out\n");
return 0;
}
...
}
Should this fix be extended, or a second patch added, to introduce a similar
phy_initialized flag for qmp_usb_runtime_suspend() and
qmp_usb_runtime_resume() in phy-qcom-qmp-usb.c?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721-qcom-usb-phy-fix-null-v5-0-a181e2adbd2d@oss.qualcomm.com?part=3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v5 4/5] phy: qcom: qmp-usb-legacy: Prevent unnecessary PM runtime suspend at boot
2026-07-21 13:05 [PATCH v5 0/5] phy: qcom: Fix possible NULL-deref and runtime PM race conditions Loic Poulain
` (2 preceding siblings ...)
2026-07-21 13:05 ` [PATCH v5 3/5] phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime suspend Loic Poulain
@ 2026-07-21 13:05 ` Loic Poulain
2026-07-21 13:05 ` [PATCH v5 5/5] phy: qcom: snps-femto-v2: Fix possible NULL-deref on early runtime suspend Loic Poulain
4 siblings, 0 replies; 10+ messages in thread
From: Loic Poulain @ 2026-07-21 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Dmitry Baryshkov, Wesley Cheng
Cc: linux-arm-msm, linux-phy, linux-kernel, Abel Vesa,
Dmitry Baryshkov, Loic Poulain
Runtime PM has to be enabled before creating the PHY, since phy_create()
only enables runtime PM on the PHY device if it is already enabled on
this parent device. This opens a small window where the device can be
runtime suspended after pm_runtime_enable() and before the later
pm_runtime_forbid(), causing an unnecessary suspend/resume cycle while
the PHY is not yet registered.
Take a runtime PM usage reference with pm_runtime_get_noresume() before
enabling runtime PM and release it once the PHY has been created to
prevent the device from being runtime suspended during that window.
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index fc490589c8e4888770807a60170905a1c7610421..eb1826fb26f0868f7758245b0cbe1a0590fea9a3 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -1285,10 +1285,16 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ /*
+ * Enable runtime PM before creating the PHY, phy_create() only enables
+ * it on the PHY device if already enabled on the parent. Hold a usage
+ * reference so callbacks cannot run before qmp->phy is assigned.
+ */
+ pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
- goto err_node_put;
+ goto err_pm_put;
/*
* Prevent runtime pm from being ON by default. Users can enable
* it using power/control in sysfs.
@@ -1297,23 +1303,27 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
ret = phy_pipe_clk_register(qmp, np);
if (ret)
- goto err_node_put;
+ goto err_pm_put;
qmp->phy = devm_phy_create(dev, np, &qmp_usb_legacy_phy_ops);
if (IS_ERR(qmp->phy)) {
ret = PTR_ERR(qmp->phy);
dev_err(dev, "failed to create PHY: %d\n", ret);
- goto err_node_put;
+ goto err_pm_put;
}
phy_set_drvdata(qmp->phy, qmp);
+ pm_runtime_put(dev);
+
of_node_put(np);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
+err_pm_put:
+ pm_runtime_put_noidle(dev);
err_node_put:
of_node_put(np);
return ret;
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v5 5/5] phy: qcom: snps-femto-v2: Fix possible NULL-deref on early runtime suspend
2026-07-21 13:05 [PATCH v5 0/5] phy: qcom: Fix possible NULL-deref and runtime PM race conditions Loic Poulain
` (3 preceding siblings ...)
2026-07-21 13:05 ` [PATCH v5 4/5] phy: qcom: qmp-usb-legacy: Prevent unnecessary PM runtime suspend at boot Loic Poulain
@ 2026-07-21 13:05 ` Loic Poulain
4 siblings, 0 replies; 10+ messages in thread
From: Loic Poulain @ 2026-07-21 13:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Dmitry Baryshkov, Wesley Cheng
Cc: linux-arm-msm, linux-phy, linux-kernel, Dmitry Baryshkov,
Konrad Dybcio, Abel Vesa, Loic Poulain
Runtime PM must be enabled before creating the PHY, since phy_create()
only enables runtime PM on the PHY device if it is already enabled on
this parent device. However, the runtime PM callbacks dereference the
hsphy instance, which is not yet ready, leaving a window where a suspend
callback may trigger a NULL pointer dereference.
Take a runtime PM usage reference with pm_runtime_get_noresume() before
enabling runtime PM and release it once the PHY has been created, so that
no runtime suspend can run before the PHY is ready. This also prevents a
short window where an unnecessary runtime suspend can occur.
Use the devres-managed version to ensure PM runtime is symmetrically
disabled during driver removal for proper cleanup.
Fixes: 0d75f508a9d5 ("phy: qcom-snps: Add runtime suspend and resume handlers")
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
index eb0b0f61d98e03963bf92e5c822334f52636abe7..b1a85518fed0a7a35516d16da3ebf69afe760e40 100644
--- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
+++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
@@ -599,8 +599,18 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
return dev_err_probe(dev, ret,
"failed to get regulator supplies\n");
+ /*
+ * Enable runtime PM before creating the PHY, phy_create() only enables
+ * it on the PHY device if already enabled on the parent. Hold a usage
+ * reference so callbacks cannot run before the PHY is ready.
+ */
+ pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
+ ret = devm_pm_runtime_enable(dev);
+ if (ret) {
+ pm_runtime_put_noidle(dev);
+ return ret;
+ }
/*
* Prevent runtime pm from being ON by default. Users can enable
* it using power/control in sysfs.
@@ -611,6 +621,7 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
if (IS_ERR(generic_phy)) {
ret = PTR_ERR(generic_phy);
dev_err(dev, "failed to create phy, %d\n", ret);
+ pm_runtime_put_noidle(dev);
return ret;
}
hsphy->phy = generic_phy;
@@ -622,8 +633,8 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (!IS_ERR(phy_provider))
dev_dbg(dev, "Registered Qcom-SNPS HS phy\n");
- else
- pm_runtime_disable(dev);
+
+ pm_runtime_put(dev);
return PTR_ERR_OR_ZERO(phy_provider);
}
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 10+ messages in thread