Skip to content

Commit 57be09c

Browse files
Navidemalexdeucher
authored andcommitted
drm/amdgpu: fix multiple memory leaks in acp_hw_init
In acp_hw_init there are some allocations that needs to be released in case of failure: 1- adev->acp.acp_genpd should be released if any allocation attemp for adev->acp.acp_cell, adev->acp.acp_res or i2s_pdata fails. 2- all of those allocations should be released if mfd_add_hotplug_devices or pm_genpd_add_device fail. 3- Release is needed in case of time out values expire. Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 815fb4c commit 57be09c

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

Diff for: drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c

+22-12
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ static int acp_hw_init(void *handle)
189189
u32 val = 0;
190190
u32 count = 0;
191191
struct device *dev;
192-
struct i2s_platform_data *i2s_pdata;
192+
struct i2s_platform_data *i2s_pdata = NULL;
193193

194194
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
195195

@@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
231231
adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
232232
GFP_KERNEL);
233233

234-
if (adev->acp.acp_cell == NULL)
235-
return -ENOMEM;
234+
if (adev->acp.acp_cell == NULL) {
235+
r = -ENOMEM;
236+
goto failure;
237+
}
236238

237239
adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
238240
if (adev->acp.acp_res == NULL) {
239-
kfree(adev->acp.acp_cell);
240-
return -ENOMEM;
241+
r = -ENOMEM;
242+
goto failure;
241243
}
242244

243245
i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
244246
if (i2s_pdata == NULL) {
245-
kfree(adev->acp.acp_res);
246-
kfree(adev->acp.acp_cell);
247-
return -ENOMEM;
247+
r = -ENOMEM;
248+
goto failure;
248249
}
249250

250251
switch (adev->asic_type) {
@@ -341,14 +342,14 @@ static int acp_hw_init(void *handle)
341342
r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,
342343
ACP_DEVS);
343344
if (r)
344-
return r;
345+
goto failure;
345346

346347
for (i = 0; i < ACP_DEVS ; i++) {
347348
dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
348349
r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
349350
if (r) {
350351
dev_err(dev, "Failed to add dev to genpd\n");
351-
return r;
352+
goto failure;
352353
}
353354
}
354355

@@ -367,7 +368,8 @@ static int acp_hw_init(void *handle)
367368
break;
368369
if (--count == 0) {
369370
dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
370-
return -ETIMEDOUT;
371+
r = -ETIMEDOUT;
372+
goto failure;
371373
}
372374
udelay(100);
373375
}
@@ -384,7 +386,8 @@ static int acp_hw_init(void *handle)
384386
break;
385387
if (--count == 0) {
386388
dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
387-
return -ETIMEDOUT;
389+
r = -ETIMEDOUT;
390+
goto failure;
388391
}
389392
udelay(100);
390393
}
@@ -393,6 +396,13 @@ static int acp_hw_init(void *handle)
393396
val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
394397
cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
395398
return 0;
399+
400+
failure:
401+
kfree(i2s_pdata);
402+
kfree(adev->acp.acp_res);
403+
kfree(adev->acp.acp_cell);
404+
kfree(adev->acp.acp_genpd);
405+
return r;
396406
}
397407

398408
/**

0 commit comments

Comments
 (0)