[PATCH v3 16/16] drm/amdgpu: validate hw_init function pointers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux