All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Hongliang Yang" <hongliang.yang@cixtech.com>
Cc: linux-phy@lists.infradead.org, robh@kernel.org,
	conor+dt@kernel.org, devicetree@vger.kernel.org,
	vkoul@kernel.org, neil.armstrong@linaro.org, olteanv@gmail.com
Subject: Re: [PATCH v1 2/4] phy: cix: Add CIX Sky1 USB3 PHY driver
Date: Mon, 31 Aug 2026 08:33:38 +0000	[thread overview]
Message-ID: <20260831083339.3DBE21F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260831082309.3854507-3-hongliang.yang@cixtech.com>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Uninitialized pointer dereference and double-free of OF node reference on probe error path.
- [High] The probe function fails to propagate error codes and always returns 0 (success) on failure paths.
- [High] Missing cleanup for dynamically allocated `phy_lookup` entries causes a memory leak and Use-After-Free.
- [High] Hardware resets are unconditionally asserted without locking after the PHY provider is registered, creating a race condition with consumer initialization.
- [Medium] The error path in `sky1_u3phy_init` mistakenly deasserts the hardware resets instead of asserting them.
- [Medium] Missing `MODULE_DEVICE_TABLE(of, ...)` macro prevents automatic module loading.
--

commit 2c8f0e43d1973dd21cdeec9d0d419e0f7d1939aa
Author: Hongliang Yang <hongliang.yang@cixtech.com>

    phy: cix: Add CIX Sky1 USB3 PHY driver
    
This patch adds a new PHY driver for the USB3 PHY found on CIX Sky1 SoCs.
The driver handles initialization, reset, and clock management for the
multi-port USB3 PHY.

> diff --git a/drivers/phy/cix/phy-cix-usb3.c b/drivers/phy/cix/phy-cix-usb3.c
> new file mode 100644
> index 0000000000000..3b6e2669b09d8
> --- /dev/null
> +++ b/drivers/phy/cix/phy-cix-usb3.c
[ ... ]
> +static int sky1_u3phy_init(struct cix_u3phy *u3phy)
> +{
[ ... ]
> +disable_ref_clk:
> +	clk_disable_unprepare(u3phy->ref_clk);
> +disable_apb_clk:
> +	clk_disable_unprepare(u3phy->apb_clk);
> +assert_reset_preset:
> +	reset_control_deassert(u3phy->preset);
> +	reset_control_deassert(u3phy->reset);

[Severity: Medium]
Does this error path correctly assert the reset lines? 

The code calls reset_control_deassert() instead of reset_control_assert(),
which leaves the PHY in a deasserted reset state while its clocks are
disabled. This might violate the intended quiescent hardware state and
could potentially lead to hardware lockups or excessive power consumption.

> +	u3phy->init = false;
> +	return ret;
> +}
[ ... ]
> +static int cix_u3phy_probe(struct platform_device *pdev)
> +{
[ ... ]
> +	device_for_each_child_node(dev, child_fn) {
> +		child_np = to_of_node(child_fn);
> +		if (!strncmp(fwnode_get_name(child_fn), "usb-port", 8) ||
> +		    !strncmp(fwnode_get_name(child_fn), "USB", 3))
> +			phy = devm_phy_create(dev, child_np, &cix_u3phy_ops);
> +		else
> +			continue;
> +		if (IS_ERR(phy)) {
> +			dev_err(dev, "failed to create phy: %s\n",
> +				fwnode_get_name(child_fn));
> +			goto put_child;

[Severity: High]
Does this error path intentionally return 0 instead of propagating the
error code?

The variable 'ret' is initialized to 0 and is not updated with the error
from devm_phy_create() before jumping to the cleanup label. This causes
the kernel framework to consider the driver successfully probed despite
the initialization failure.

> +		}
> +		phy_set_drvdata(phy, u3phy);
> +		phy_create_lookup(phy, fwnode_get_name(child_fn), dev_name(dev));

[Severity: High]
Is there a corresponding cleanup mechanism for this dynamically allocated
phy_lookup entry? 

The driver creates lookup entries using phy_create_lookup() but does not
seem to provide a .remove callback or devres action to call
phy_remove_lookup(). When the driver is unbound, devres frees the struct
phy, leaving dangling pointers in the global lookup list which could cause
a use-after-free for subsequent lookups by consumers.

> +	}
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	if (IS_ERR(phy_provider)) {
> +		dev_err(dev, "failed to register phy provider\n");
> +		goto put_child;

[Severity: High]
Similar to the devm_phy_create() error path, does this drop the error code
from devm_of_phy_provider_register()?

Additionally, does jumping to put_child here cause a double-free or a
dereference of an uninitialized pointer? 

If the device_for_each_child_node loop executed zero times, child_np is
completely uninitialized. If the loop executed at least once and completed
normally, child_np holds a pointer to the last child whose reference was
already released by the iterator's final condition check.

> +	}
> +	reset_control_assert(u3phy->reset);
> +	reset_control_assert(u3phy->preset);

[Severity: High]
Is it safe to unconditionally assert these hardware resets here without
locking after the PHY provider is registered? 

A deferred consumer could immediately acquire the exposed PHY and call
phy_init(), which initializes the PHY and deasserts resets while holding a
mutex. Concurrently, this probe function unconditionally executes
reset_control_assert() without holding the mutex, which might forcefully
reset the active PHY hardware.

> +	return 0;
> +
> +put_child:
> +	of_node_put(child_np);
> +	return ret;
> +}
> +
> +static const struct of_device_id cix_u3phy_dt_match[] = {
> +	{
> +		.compatible = "cix,sky1-usb3-phy",
> +		.data = &sky1_u3phy_cfg
> +	},
> +	{ /* sentinel */ }
> +};

[Severity: Medium]
Is the MODULE_DEVICE_TABLE(of, ...) macro missing here? 

Without it, the driver module cannot be automatically loaded by udev or kmod
based on the Device Tree compatible string.

> +
> +static struct platform_driver cix_usb3_phy_driver = {
> +	.probe		= cix_u3phy_probe,
> +	.driver		= {
> +		.name	= "cix-usb3-phy",
> +		.of_match_table = cix_u3phy_dt_match,
> +	},
> +};

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260831082309.3854507-1-hongliang.yang@cixtech.com?part=2

WARNING: multiple messages have this Message-ID (diff)
From: sashiko-bot@kernel.org
To: "Hongliang Yang" <hongliang.yang@cixtech.com>
Cc: linux-phy@lists.infradead.org, robh@kernel.org,
	conor+dt@kernel.org, devicetree@vger.kernel.org,
	vkoul@kernel.org, neil.armstrong@linaro.org, olteanv@gmail.com
Subject: Re: [PATCH v1 2/4] phy: cix: Add CIX Sky1 USB3 PHY driver
Date: Mon, 31 Aug 2026 08:33:38 +0000	[thread overview]
Message-ID: <20260831083339.3DBE21F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260831082309.3854507-3-hongliang.yang@cixtech.com>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Uninitialized pointer dereference and double-free of OF node reference on probe error path.
- [High] The probe function fails to propagate error codes and always returns 0 (success) on failure paths.
- [High] Missing cleanup for dynamically allocated `phy_lookup` entries causes a memory leak and Use-After-Free.
- [High] Hardware resets are unconditionally asserted without locking after the PHY provider is registered, creating a race condition with consumer initialization.
- [Medium] The error path in `sky1_u3phy_init` mistakenly deasserts the hardware resets instead of asserting them.
- [Medium] Missing `MODULE_DEVICE_TABLE(of, ...)` macro prevents automatic module loading.
--

commit 2c8f0e43d1973dd21cdeec9d0d419e0f7d1939aa
Author: Hongliang Yang <hongliang.yang@cixtech.com>

    phy: cix: Add CIX Sky1 USB3 PHY driver
    
This patch adds a new PHY driver for the USB3 PHY found on CIX Sky1 SoCs.
The driver handles initialization, reset, and clock management for the
multi-port USB3 PHY.

> diff --git a/drivers/phy/cix/phy-cix-usb3.c b/drivers/phy/cix/phy-cix-usb3.c
> new file mode 100644
> index 0000000000000..3b6e2669b09d8
> --- /dev/null
> +++ b/drivers/phy/cix/phy-cix-usb3.c
[ ... ]
> +static int sky1_u3phy_init(struct cix_u3phy *u3phy)
> +{
[ ... ]
> +disable_ref_clk:
> +	clk_disable_unprepare(u3phy->ref_clk);
> +disable_apb_clk:
> +	clk_disable_unprepare(u3phy->apb_clk);
> +assert_reset_preset:
> +	reset_control_deassert(u3phy->preset);
> +	reset_control_deassert(u3phy->reset);

[Severity: Medium]
Does this error path correctly assert the reset lines? 

The code calls reset_control_deassert() instead of reset_control_assert(),
which leaves the PHY in a deasserted reset state while its clocks are
disabled. This might violate the intended quiescent hardware state and
could potentially lead to hardware lockups or excessive power consumption.

> +	u3phy->init = false;
> +	return ret;
> +}
[ ... ]
> +static int cix_u3phy_probe(struct platform_device *pdev)
> +{
[ ... ]
> +	device_for_each_child_node(dev, child_fn) {
> +		child_np = to_of_node(child_fn);
> +		if (!strncmp(fwnode_get_name(child_fn), "usb-port", 8) ||
> +		    !strncmp(fwnode_get_name(child_fn), "USB", 3))
> +			phy = devm_phy_create(dev, child_np, &cix_u3phy_ops);
> +		else
> +			continue;
> +		if (IS_ERR(phy)) {
> +			dev_err(dev, "failed to create phy: %s\n",
> +				fwnode_get_name(child_fn));
> +			goto put_child;

[Severity: High]
Does this error path intentionally return 0 instead of propagating the
error code?

The variable 'ret' is initialized to 0 and is not updated with the error
from devm_phy_create() before jumping to the cleanup label. This causes
the kernel framework to consider the driver successfully probed despite
the initialization failure.

> +		}
> +		phy_set_drvdata(phy, u3phy);
> +		phy_create_lookup(phy, fwnode_get_name(child_fn), dev_name(dev));

[Severity: High]
Is there a corresponding cleanup mechanism for this dynamically allocated
phy_lookup entry? 

The driver creates lookup entries using phy_create_lookup() but does not
seem to provide a .remove callback or devres action to call
phy_remove_lookup(). When the driver is unbound, devres frees the struct
phy, leaving dangling pointers in the global lookup list which could cause
a use-after-free for subsequent lookups by consumers.

> +	}
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	if (IS_ERR(phy_provider)) {
> +		dev_err(dev, "failed to register phy provider\n");
> +		goto put_child;

[Severity: High]
Similar to the devm_phy_create() error path, does this drop the error code
from devm_of_phy_provider_register()?

Additionally, does jumping to put_child here cause a double-free or a
dereference of an uninitialized pointer? 

If the device_for_each_child_node loop executed zero times, child_np is
completely uninitialized. If the loop executed at least once and completed
normally, child_np holds a pointer to the last child whose reference was
already released by the iterator's final condition check.

> +	}
> +	reset_control_assert(u3phy->reset);
> +	reset_control_assert(u3phy->preset);

[Severity: High]
Is it safe to unconditionally assert these hardware resets here without
locking after the PHY provider is registered? 

A deferred consumer could immediately acquire the exposed PHY and call
phy_init(), which initializes the PHY and deasserts resets while holding a
mutex. Concurrently, this probe function unconditionally executes
reset_control_assert() without holding the mutex, which might forcefully
reset the active PHY hardware.

> +	return 0;
> +
> +put_child:
> +	of_node_put(child_np);
> +	return ret;
> +}
> +
> +static const struct of_device_id cix_u3phy_dt_match[] = {
> +	{
> +		.compatible = "cix,sky1-usb3-phy",
> +		.data = &sky1_u3phy_cfg
> +	},
> +	{ /* sentinel */ }
> +};

[Severity: Medium]
Is the MODULE_DEVICE_TABLE(of, ...) macro missing here? 

Without it, the driver module cannot be automatically loaded by udev or kmod
based on the Device Tree compatible string.

> +
> +static struct platform_driver cix_usb3_phy_driver = {
> +	.probe		= cix_u3phy_probe,
> +	.driver		= {
> +		.name	= "cix-usb3-phy",
> +		.of_match_table = cix_u3phy_dt_match,
> +	},
> +};

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260831082309.3854507-1-hongliang.yang@cixtech.com?part=2

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

  reply	other threads:[~2026-08-31  8:33 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31  8:23 [PATCH v1 0/4] Add CIX Sky1 USB3/USBSSP support Hongliang Yang
2026-08-31  8:23 ` Hongliang Yang
2026-08-31  8:23 ` [PATCH v1 1/4] dt-bindings: Add CIX Sky1 USB bindings Hongliang Yang
2026-08-31  8:23   ` Hongliang Yang
2026-08-31  8:32   ` sashiko-bot
2026-08-31  8:32     ` sashiko-bot
2026-08-31 16:07   ` Conor Dooley
2026-08-31 16:07     ` Conor Dooley
2026-09-01  5:47   ` Krzysztof Kozlowski
2026-09-01  5:47     ` Krzysztof Kozlowski
2026-09-02  3:23     ` Hongliang Yang
2026-09-02  3:23       ` Hongliang Yang
2026-09-03  6:28       ` Krzysztof Kozlowski
2026-09-03  6:28         ` Krzysztof Kozlowski
2026-09-03  2:35     ` [PATCH v3 0/5] Add CIX Sky1 USB3/USBSSP support Hongliang Yang
2026-09-03  2:35       ` Hongliang Yang
2026-09-03  2:35       ` [PATCH v3 1/5] dt-bindings: phy: Add CIX Sky1 USB3 PHY Hongliang Yang
2026-09-03  2:35         ` Hongliang Yang
2026-09-03  2:35       ` [PATCH v3 2/5] dt-bindings: usb: Add CIX Sky1 USBSSP controller Hongliang Yang
2026-09-03  2:35         ` Hongliang Yang
2026-09-03  6:30         ` Krzysztof Kozlowski
2026-09-03  6:30           ` Krzysztof Kozlowski
2026-09-03  2:35       ` [PATCH v3 3/5] phy: cix: Add CIX Sky1 USB3 PHY driver Hongliang Yang
2026-09-03  2:35         ` Hongliang Yang
2026-09-03  2:48         ` sashiko-bot
2026-09-03  2:48           ` sashiko-bot
2026-09-03  2:35       ` [PATCH v3 4/5] usb: cdns3: Add CIX Sky1 glue driver Hongliang Yang
2026-09-03  2:35         ` Hongliang Yang
2026-09-03  2:45         ` sashiko-bot
2026-09-03  2:45           ` sashiko-bot
2026-09-03  2:35       ` [PATCH v3 5/5] arm64: dts: cix: Add USB4/USB5 nodes for Sky1 Hongliang Yang
2026-09-03  2:35         ` Hongliang Yang
2026-09-03  6:29       ` [PATCH v3 0/5] Add CIX Sky1 USB3/USBSSP support Krzysztof Kozlowski
2026-09-03  6:29         ` Krzysztof Kozlowski
2026-08-31  8:23 ` [PATCH v1 2/4] phy: cix: Add CIX Sky1 USB3 PHY driver Hongliang Yang
2026-08-31  8:23   ` Hongliang Yang
2026-08-31  8:33   ` sashiko-bot [this message]
2026-08-31  8:33     ` sashiko-bot
2026-08-31  8:23 ` [PATCH v1 3/4] usb: cdns3: Add CIX Sky1 glue driver Hongliang Yang
2026-08-31  8:23   ` Hongliang Yang
2026-08-31  8:41   ` sashiko-bot
2026-08-31  8:41     ` sashiko-bot
2026-08-31  8:57   ` Philipp Zabel
2026-08-31  8:57     ` Philipp Zabel
2026-08-31  8:23 ` [PATCH v1 4/4] arm64: dts: cix: Add USB4/USB5 nodes for Sky1 Hongliang Yang
2026-08-31  8:23   ` Hongliang Yang
2026-08-31  8:33   ` sashiko-bot
2026-08-31  8:33     ` sashiko-bot
2026-09-02  3:21 ` [PATCH v2 0/5] Add CIX Sky1 USB3/USBSSP support Hongliang Yang
2026-09-02  3:21   ` Hongliang Yang
2026-09-02  3:21 ` [PATCH v2 1/5] dt-bindings: phy: Add CIX Sky1 USB3 PHY Hongliang Yang
2026-09-02  3:21   ` Hongliang Yang
2026-09-02  3:21 ` [PATCH v2 2/5] dt-bindings: usb: Add CIX Sky1 USBSSP controller Hongliang Yang
2026-09-02  3:21   ` Hongliang Yang
2026-09-02  3:21 ` [PATCH v2 3/5] phy: cix: Add CIX Sky1 USB3 PHY driver Hongliang Yang
2026-09-02  3:21   ` Hongliang Yang
2026-09-02  3:32   ` sashiko-bot
2026-09-02  3:32     ` sashiko-bot
2026-09-02  3:21 ` [PATCH v2 4/5] usb: cdns3: Add CIX Sky1 glue driver Hongliang Yang
2026-09-02  3:21   ` Hongliang Yang
2026-09-02  3:32   ` sashiko-bot
2026-09-02  3:32     ` sashiko-bot
2026-09-02  3:21 ` [PATCH v2 5/5] arm64: dts: cix: Add USB4/USB5 nodes for Sky1 Hongliang Yang
2026-09-02  3:21   ` Hongliang Yang

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=20260831083339.3DBE21F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=hongliang.yang@cixtech.com \
    --cc=linux-phy@lists.infradead.org \
    --cc=neil.armstrong@linaro.org \
    --cc=olteanv@gmail.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vkoul@kernel.org \
    /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.