drm/amdgpu: fix Null pointer dereference error in amdgpu_device_recover_vram
authorHoratio Zhang <Hongkun.Zhang@amd.com>
Mon, 29 May 2023 18:23:37 +0000 (14:23 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Jun 2023 09:15:22 +0000 (11:15 +0200)
[ Upstream commit 2a1eb1a343208ce7d6839b73d62aece343e693ff ]

Use the function of amdgpu_bo_vm_destroy to handle the resource release
of shadow bo. During the amdgpu_mes_self_test, shadow bo released, but
vmbo->shadow_list was not, which caused a null pointer reference error
in amdgpu_device_recover_vram when GPU reset.

Fixes: 6c032c37ac3e ("drm/amdgpu: Fix vram recover doesn't work after whole GPU reset (v2)")
Signed-off-by: xinhui pan <xinhui.pan@amd.com>
Signed-off-by: Horatio Zhang <Hongkun.Zhang@amd.com>
Acked-by: Feifei Xu <Feifei.Xu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c

index 4feedf518a1916a6e8afe921f3fbfd006473d666..ad8cb9e6d1ab0ae3725a44ab09f51a84a7555f8d 100644 (file)
@@ -79,9 +79,10 @@ static void amdgpu_bo_user_destroy(struct ttm_buffer_object *tbo)
 static void amdgpu_bo_vm_destroy(struct ttm_buffer_object *tbo)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
-       struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo);
+       struct amdgpu_bo *shadow_bo = ttm_to_amdgpu_bo(tbo), *bo;
        struct amdgpu_bo_vm *vmbo;
 
+       bo = shadow_bo->parent;
        vmbo = to_amdgpu_bo_vm(bo);
        /* in case amdgpu_device_recover_vram got NULL of bo->parent */
        if (!list_empty(&vmbo->shadow_list)) {
@@ -691,11 +692,6 @@ int amdgpu_bo_create_vm(struct amdgpu_device *adev,
                return r;
 
        *vmbo_ptr = to_amdgpu_bo_vm(bo_ptr);
-       INIT_LIST_HEAD(&(*vmbo_ptr)->shadow_list);
-       /* Set destroy callback to amdgpu_bo_vm_destroy after vmbo->shadow_list
-        * is initialized.
-        */
-       bo_ptr->tbo.destroy = &amdgpu_bo_vm_destroy;
        return r;
 }
 
@@ -712,6 +708,8 @@ void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo)
 
        mutex_lock(&adev->shadow_list_lock);
        list_add_tail(&vmbo->shadow_list, &adev->shadow_list);
+       vmbo->shadow->parent = amdgpu_bo_ref(&vmbo->bo);
+       vmbo->shadow->tbo.destroy = &amdgpu_bo_vm_destroy;
        mutex_unlock(&adev->shadow_list_lock);
 }
 
index 01e42bdd8e4e891c4b016905b46a32cee15b7a61..4642cff0e1a4f3888f17f24b93db594a2f74eb7c 100644 (file)
@@ -564,7 +564,6 @@ int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                return r;
        }
 
-       (*vmbo)->shadow->parent = amdgpu_bo_ref(bo);
        amdgpu_bo_add_to_shadow_list(*vmbo);
 
        return 0;