Skip to contentSkip to conversation

FAILED: patch "[PATCH] drm/amdgpu: fix ACP MFD device leak on init failure" failed to apply to 5.10-stable tree

PATCH New [email protected] 2 participants 2 messages Oct 5

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x f0013046151b7467e62c471c1c83d63ea255799c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026100553-flattered-brought-ee78@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From f0013046151b7467e62c471c1c83d63ea255799c Mon Sep 17 00:00:00 2001
From: Guangshuo Li <[email protected]>
Date: Mon, 21 Sep 2026 18:33:18 +0800
Subject: [PATCH] drm/amdgpu: fix ACP MFD device leak on init failure

acp_hw_init() registers ACP child devices with mfd_add_devices() before attaching them to the ACP power domain and initializing the hardware.

If attaching a child to the power domain fails, or if the ACP reset or clock enable operation times out, the failure path frees only the source cell, resource, and platform-data allocations. The child platform devices already registered by mfd_add_devices() remain registered and are never released.

Remove the children from the power domain and unregister the MFD devices on failures that occur after mfd_add_devices() succeeds. Keep mfd_add_devices() failures on the existing cleanup path since the MFD core already rolls back partially registered children itself.

The issue was identified by a static analysis tool I developed and confirmed by manual review.

Fixes 25030321ba28 ("drm/amd: add pm domain for ACP IP sub blocks")
(cherry picked from commit 63da68d6a2279ec945581c990c5a59a5ae8b5560)
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +9 -4
index 9014678d75ab..be4d00ac96b3 100644
@@ -318,7 +318,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
 		r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
 					  acp_genpd_add_device);
 		if (r)
-			goto failure;
+			goto failure_remove_mfd;
 		break;
 	}
 	default:
@@ -443,7 +443,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
 		r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
 					  acp_genpd_add_device);
 		if (r)
-			goto failure;
+			goto failure_remove_mfd;
 	}
 
 	/* Assert Soft reset of ACP */
@@ -461,7 +461,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
 		if (--count == 0) {
 			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
 			r = -ETIMEDOUT;
-			goto failure;
+			goto failure_remove_mfd;
 		}
 		udelay(100);
 	}
@@ -479,7 +479,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
 		if (--count == 0) {
 			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
 			r = -ETIMEDOUT;
-			goto failure;
+			goto failure_remove_mfd;
 		}
 		udelay(100);
 	}
@@ -489,6 +489,11 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
 	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
 	return 0;
 
+failure_remove_mfd:
+	device_for_each_child(adev->acp.parent, NULL,
+			      acp_genpd_remove_device);
+	mfd_remove_devices(adev->acp.parent);
+
 failure:
 	kfree(adev->acp.i2s_pdata);
 	kfree(adev->acp.acp_res);
maintainer
#1 lore raw

PATCH 1/1 drm/amdgpu: fix ACP MFD device leak on init failure

From: Guangshuo Li <[email protected]>

[ Upstream commit f0013046151b7467e62c471c1c83d63ea255799c ]

acp_hw_init() registers ACP child devices with mfd_add_devices() before attaching them to the ACP power domain and initializing the hardware.

If attaching a child to the power domain fails, or if the ACP reset or clock enable operation times out, the failure path frees only the source cell, resource, and platform-data allocations. The child platform devices already registered by mfd_add_devices() remain registered and are never released.

Remove the children from the power domain and unregister the MFD devices on failures that occur after mfd_add_devices() succeeds. Keep mfd_add_devices() failures on the existing cleanup path since the MFD core already rolls back partially registered children itself.

The issue was identified by a static analysis tool I developed and confirmed by manual review.

Fixes 25030321ba28 ("drm/amd: add pm domain for ACP IP sub blocks")
(cherry picked from commit 63da68d6a2279ec945581c990c5a59a5ae8b5560)
[ sashal: adapted the error-path changes to the single device_for_each_child() call in acp_hw_init(). ]
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +8 -3
index 173ac5677d467..0f359f1fb041b 100644
@@ -354,7 +354,7 @@ static int acp_hw_init(void *handle)
 	r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
 				  acp_genpd_add_device);
 	if (r)
-		goto failure;
+		goto failure_remove_mfd;
 
 	/* Assert Soft reset of ACP */
 	val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
@@ -371,7 +371,7 @@ static int acp_hw_init(void *handle)
 		if (--count == 0) {
 			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
 			r = -ETIMEDOUT;
-			goto failure;
+			goto failure_remove_mfd;
 		}
 		udelay(100);
 	}
@@ -389,7 +389,7 @@ static int acp_hw_init(void *handle)
 		if (--count == 0) {
 			dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
 			r = -ETIMEDOUT;
-			goto failure;
+			goto failure_remove_mfd;
 		}
 		udelay(100);
 	}
@@ -399,6 +399,11 @@ static int acp_hw_init(void *handle)
 	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
 	return 0;
 
+failure_remove_mfd:
+	device_for_each_child(adev->acp.parent, NULL,
+			      acp_genpd_remove_device);
+	mfd_remove_devices(adev->acp.parent);
+
 failure:
 	kfree(i2s_pdata);
 	kfree(adev->acp.acp_res);
Signature · 1 line
2.53.0