In hi3670_pcie_get_resources_from_pcie(), the reference obtained via bus_find_device_by_of_node() is never released with put_device(). Each call to this function increments the reference count of the PCIe device without decrementing it, preventing proper device cleanup. And the device node obtained via of_get_child_by_name() is never released with of_node_put(). This could cause a leak of the node reference.
Add proper resource cleanup using goto labels to ensure all acquired references are released before function return, regardless of the exit path.
Found by code review.
Cc: stable@vger.kernel.org Fixes: 73075011ffff ("phy: HiSilicon: Add driver for Kirin 970 PCIe PHY") Signed-off-by: Ma Ke make24@iscas.ac.cn --- drivers/phy/hisilicon/phy-hi3670-pcie.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/hisilicon/phy-hi3670-pcie.c b/drivers/phy/hisilicon/phy-hi3670-pcie.c index dbc7dcce682b..4c67a7613261 100644 --- a/drivers/phy/hisilicon/phy-hi3670-pcie.c +++ b/drivers/phy/hisilicon/phy-hi3670-pcie.c @@ -560,7 +560,8 @@ static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy) { struct device_node *pcie_port; struct device *dev = phy->dev; - struct device *pcie_dev; + struct device *pcie_dev = NULL; + int ret = 0;
pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie"); if (!pcie_port) { @@ -572,7 +573,8 @@ static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy) pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port); if (!pcie_dev) { dev_err(dev, "Didn't find pcie device\n"); - return -ENODEV; + ret = -ENODEV; + goto out_put_node; }
/* @@ -586,9 +588,14 @@ static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy) phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb"); if (!phy->apb) { dev_err(dev, "Failed to get APB regmap\n"); - return -ENODEV; + ret = -ENODEV; + goto out_put_device; }
+out_put_device: + put_device(pcie_dev); +out_put_node: + of_node_put(pcie_port); return 0; }
Hi Ma,
kernel test robot noticed the following build warnings:
[auto build test WARNING on akpm-mm/mm-everything] [also build test WARNING on linus/master v6.18-rc5 next-20251114] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ma-Ke/phy-HiSilicon-Fix-error... base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20251116073231.22676-1-make24%40iscas.ac.cn patch subject: [PATCH] phy: HiSilicon: Fix error handling in hi3670_pcie_get_resources_from_pcie config: m68k-randconfig-r072-20251117 (https://download.01.org/0day-ci/archive/20251117/202511170524.sEQYJ4MB-lkp@i...) compiler: m68k-linux-gcc (GCC) 10.5.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251117/202511170524.sEQYJ4MB-lkp@i...)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot lkp@intel.com | Closes: https://lore.kernel.org/oe-kbuild-all/202511170524.sEQYJ4MB-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/phy/hisilicon/phy-hi3670-pcie.c: In function 'hi3670_pcie_get_resources_from_pcie':
drivers/phy/hisilicon/phy-hi3670-pcie.c:564:6: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
564 | int ret = 0; | ^~~
vim +/ret +564 drivers/phy/hisilicon/phy-hi3670-pcie.c
558 559 static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy) 560 { 561 struct device_node *pcie_port; 562 struct device *dev = phy->dev; 563 struct device *pcie_dev = NULL;
564 int ret = 0;
565 566 pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie"); 567 if (!pcie_port) { 568 dev_err(dev, "no pcie node found in %s\n", 569 dev->parent->of_node->full_name); 570 return -ENODEV; 571 } 572 573 pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port); 574 if (!pcie_dev) { 575 dev_err(dev, "Didn't find pcie device\n"); 576 ret = -ENODEV; 577 goto out_put_node; 578 } 579 580 /* 581 * We might just use NULL instead of the APB name, as the 582 * pcie-kirin currently registers directly just one regmap (although 583 * the DWC driver register other regmaps). 584 * 585 * Yet, it sounds safer to warrant that it will be accessing the 586 * right regmap. So, let's use the named version. 587 */ 588 phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb"); 589 if (!phy->apb) { 590 dev_err(dev, "Failed to get APB regmap\n"); 591 ret = -ENODEV; 592 goto out_put_device; 593 } 594 595 out_put_device: 596 put_device(pcie_dev); 597 out_put_node: 598 of_node_put(pcie_port); 599 return 0; 600 } 601
linux-stable-mirror@lists.linaro.org