Validate function pointer at all the places where
hw_init is called to avoid a NULL dereference.

Signed-off-by: Sunil Khatri <[email protected]>
---
 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

Reply via email to