]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amd: Fix NULL pointer dereference in device cleanup
authorMario Limonciello <mario.limonciello@amd.com>
Wed, 4 Mar 2026 20:07:40 +0000 (14:07 -0600)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 6 Mar 2026 21:25:44 +0000 (16:25 -0500)
When GPU initialization fails due to an unsupported HW block
IP blocks may have a NULL version pointer. During cleanup in
amdgpu_device_fini_hw, the code calls amdgpu_device_set_pg_state and
amdgpu_device_set_cg_state which iterate over all IP blocks and access
adev->ip_blocks[i].version without NULL checks, leading to a kernel
NULL pointer dereference.

Add NULL checks for adev->ip_blocks[i].version in both
amdgpu_device_set_cg_state and amdgpu_device_set_pg_state to prevent
dereferencing NULL pointers during GPU teardown when initialization has
failed.

Fixes: 39fc2bc4da00 ("drm/amdgpu: Protect GPU register accesses in powergated state in some paths")
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

index 6f6973e8cd5374a7c2d66404e109b3465d9da2cf..f7309705788d3cfd48dc9bdb62c7ab4ca61fe865 100644 (file)
@@ -2550,6 +2550,8 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
                i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
                if (!adev->ip_blocks[i].status.late_initialized)
                        continue;
+               if (!adev->ip_blocks[i].version)
+                       continue;
                /* skip CG for GFX, SDMA on S0ix */
                if (adev->in_s0ix &&
                    (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
@@ -2589,6 +2591,8 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
                i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
                if (!adev->ip_blocks[i].status.late_initialized)
                        continue;
+               if (!adev->ip_blocks[i].version)
+                       continue;
                /* skip PG for GFX, SDMA on S0ix */
                if (adev->in_s0ix &&
                    (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||