Validate function pointer at all the places where hw_init is called to avoid a NULL dereference. Signed-off-by: Sunil Khatri <sunil.khatri@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 82 ++++++++++++++-------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b9ca5b1cde0c..4142acc36796 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2687,11 +2687,13 @@ static int amdgpu_device_ip_hw_init_phase1(struct amdgpu_device *adev) if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON || (amdgpu_sriov_vf(adev) && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)) || adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) { - r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]); - if (r) { - DRM_ERROR("hw_init of IP block <%s> failed %d\n", - adev->ip_blocks[i].version->funcs->name, r); - return r; + if (adev->ip_blocks[i].version->funcs->hw_init) { + r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]); + if (r) { + DRM_ERROR("hw_init of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + return r; + } } adev->ip_blocks[i].status.hw = true; } @@ -2712,11 +2714,13 @@ static int amdgpu_device_ip_hw_init_phase2(struct amdgpu_device *adev) if (!amdgpu_ip_member_of_hwini( adev, adev->ip_blocks[i].version->type)) continue; - r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]); - if (r) { - DRM_ERROR("hw_init of IP block <%s> failed %d\n", - adev->ip_blocks[i].version->funcs->name, r); - return r; + if (adev->ip_blocks[i].version->funcs->hw_init) { + r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]); + if (r) { + DRM_ERROR("hw_init of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + return r; + } } adev->ip_blocks[i].status.hw = true; } @@ -2758,11 +2762,15 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev) } } } else { - r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]); - if (r) { - DRM_ERROR("hw_init of IP block <%s> failed %d\n", - adev->ip_blocks[i].version->funcs->name, r); - return r; + if (adev->ip_blocks[i].version->funcs->hw_init) { + r = adev->ip_blocks[i].version->funcs + ->hw_init(&adev->ip_blocks[i]); + if (r) { + DRM_ERROR("hw_init of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, + r); + return r; + } } } @@ -2873,11 +2881,17 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) continue; if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) { - /* need to do common hw init early so everything is set up for gmc */ - r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]); - if (r) { - DRM_ERROR("hw_init %d failed %d\n", i, r); - goto init_failed; + if (adev->ip_blocks[i].version->funcs->hw_init) { + /* + * need to do common hw init early so everything + * is set up for gmc. + */ + r = adev->ip_blocks[i].version->funcs + ->hw_init(&adev->ip_blocks[i]); + if (r) { + DRM_ERROR("hw_init %d failed %d\n", i, r); + goto init_failed; + } } adev->ip_blocks[i].status.hw = true; } else if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { @@ -2891,10 +2905,12 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) DRM_ERROR("amdgpu_mem_scratch_init failed %d\n", r); goto init_failed; } - r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]); - if (r) { - DRM_ERROR("hw_init %d failed %d\n", i, r); - goto init_failed; + if (adev->ip_blocks[i].version->funcs->hw_init) { + r = adev->ip_blocks[i].version->funcs->hw_init(&adev->ip_blocks[i]); + if (r) { + DRM_ERROR("hw_init %d failed %d\n", i, r); + goto init_failed; + } } r = amdgpu_device_wb_init(adev); if (r) { @@ -3643,11 +3659,13 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) if (block->version->type != ip_order[j] || !block->status.valid) continue; - - r = block->version->funcs->hw_init(&adev->ip_blocks[i]); - DRM_INFO("RE-INIT-early: %s %s\n", block->version->funcs->name, r?"failed":"succeeded"); - if (r) - return r; + if (adev->ip_blocks[i].version->funcs->hw_init) { + r = block->version->funcs->hw_init(&adev->ip_blocks[i]); + DRM_INFO("RE-INIT-early: %s %s\n", block->version->funcs->name, + r?"failed":"succeeded"); + if (r) + return r; + } block->status.hw = true; } } @@ -3687,10 +3705,12 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev) if (adev->ip_blocks[i].version->funcs->resume) r = block->version->funcs->resume(&adev->ip_blocks[i]); } else { - r = block->version->funcs->hw_init(&adev->ip_blocks[i]); + if (adev->ip_blocks[i].version->funcs->hw_init) + r = block->version->funcs->hw_init(&adev->ip_blocks[i]); } - DRM_INFO("RE-INIT-late: %s %s\n", block->version->funcs->name, r?"failed":"succeeded"); + DRM_INFO("RE-INIT-late: %s %s\n", block->version->funcs->name, + r ? "failed":"succeeded"); if (r) return r; block->status.hw = true; -- 2.34.1