]> git.hungrycats.org Git - linux/commitdiff
drm/amdkfd: amdkfd_free_gtt_mem clear the correct pointer
authorPhilip Yang <Philip.Yang@amd.com>
Sun, 14 Jul 2024 15:11:05 +0000 (11:11 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 17 Nov 2024 14:07:22 +0000 (15:07 +0100)
commit c86ad39140bbcb9dc75a10046c2221f657e8083b upstream.

Pass pointer reference to amdgpu_bo_unref to clear the correct pointer,
otherwise amdgpu_bo_unref clear the local variable, the original pointer
not set to NULL, this could cause use-after-free bug.

Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Vamsi Krishna Brahmajosyula <vamsi-krishna.brahmajosyula@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c

index 5d9a34601a1ac54d3a64d57ee39128fae257e401..c31e5f9d63da2af8ffa087f5270cb385bfc978c1 100644 (file)
@@ -344,15 +344,15 @@ allocate_mem_reserve_bo_failed:
        return r;
 }
 
-void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj)
+void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void **mem_obj)
 {
-       struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj;
+       struct amdgpu_bo **bo = (struct amdgpu_bo **) mem_obj;
 
-       amdgpu_bo_reserve(bo, true);
-       amdgpu_bo_kunmap(bo);
-       amdgpu_bo_unpin(bo);
-       amdgpu_bo_unreserve(bo);
-       amdgpu_bo_unref(&(bo));
+       amdgpu_bo_reserve(*bo, true);
+       amdgpu_bo_kunmap(*bo);
+       amdgpu_bo_unpin(*bo);
+       amdgpu_bo_unreserve(*bo);
+       amdgpu_bo_unref(bo);
 }
 
 int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size,
index 4b694886715cf0b01aff35dc52a33792512aafc9..c7672a1d15609a6428eb66658f7d5c8c470908c6 100644 (file)
@@ -210,7 +210,7 @@ int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem, struct mm_struct *mm)
 int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size,
                                void **mem_obj, uint64_t *gpu_addr,
                                void **cpu_ptr, bool mqd_gfx9);
-void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj);
+void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void **mem_obj);
 int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size,
                                void **mem_obj);
 void amdgpu_amdkfd_free_gws(struct amdgpu_device *adev, void *mem_obj);
index e3cd66c4d95d8e47d0aa265c162a8f3ba5750a98..f83574107eb85b0235c92535298c455c064692b3 100644 (file)
@@ -408,7 +408,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
 
 err_create_queue:
        if (wptr_bo)
-               amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
+               amdgpu_amdkfd_free_gtt_mem(dev->adev, (void **)&wptr_bo);
 err_wptr_map_gart:
 err_alloc_doorbells:
 err_bind_process:
index 27820f0a282d16cd7532ee5e4a9a7d226dec025b..e2c055abfea9744b2b45840052997df09e6cb4f1 100644 (file)
@@ -673,7 +673,7 @@ kfd_interrupt_error:
 kfd_doorbell_error:
        kfd_gtt_sa_fini(kfd);
 kfd_gtt_sa_init_error:
-       amdgpu_amdkfd_free_gtt_mem(kfd->adev, kfd->gtt_mem);
+       amdgpu_amdkfd_free_gtt_mem(kfd->adev, &kfd->gtt_mem);
 alloc_gtt_mem_failure:
        if (kfd->gws)
                amdgpu_amdkfd_free_gws(kfd->adev, kfd->gws);
@@ -693,7 +693,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
                kfd_doorbell_fini(kfd);
                ida_destroy(&kfd->doorbell_ida);
                kfd_gtt_sa_fini(kfd);
-               amdgpu_amdkfd_free_gtt_mem(kfd->adev, kfd->gtt_mem);
+               amdgpu_amdkfd_free_gtt_mem(kfd->adev, &kfd->gtt_mem);
                if (kfd->gws)
                        amdgpu_amdkfd_free_gws(kfd->adev, kfd->gws);
        }
index 1b7b29426480479e98722524731daf90b7195b01..3ab0a796af060ea9244def1d20eddae72eab2057 100644 (file)
@@ -2392,7 +2392,7 @@ static void deallocate_hiq_sdma_mqd(struct kfd_dev *dev,
 {
        WARN(!mqd, "No hiq sdma mqd trunk to free");
 
-       amdgpu_amdkfd_free_gtt_mem(dev->adev, mqd->gtt_mem);
+       amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem);
 }
 
 void device_queue_manager_uninit(struct device_queue_manager *dqm)
index 623ccd227b7de058263941c7a300c6379c42458a..c733d6888c308896ed14f025dac80d8e0ec7297f 100644 (file)
@@ -204,7 +204,7 @@ void kfd_free_mqd_cp(struct mqd_manager *mm, void *mqd,
              struct kfd_mem_obj *mqd_mem_obj)
 {
        if (mqd_mem_obj->gtt_mem) {
-               amdgpu_amdkfd_free_gtt_mem(mm->dev->adev, mqd_mem_obj->gtt_mem);
+               amdgpu_amdkfd_free_gtt_mem(mm->dev->adev, &mqd_mem_obj->gtt_mem);
                kfree(mqd_mem_obj);
        } else {
                kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
index 5bca6abd55aeff335a398786c2e871b176d78bbb..9582c9449fff94f42d9cdc3a41e7ea153357f41c 100644 (file)
@@ -1052,7 +1052,7 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
 
                if (pdd->dev->shared_resources.enable_mes)
                        amdgpu_amdkfd_free_gtt_mem(pdd->dev->adev,
-                                                  pdd->proc_ctx_bo);
+                                                  &pdd->proc_ctx_bo);
                /*
                 * before destroying pdd, make sure to report availability
                 * for auto suspend
index 99aa8a8399d69aacc8ae2df65cd2a308f23a92cd..1918a3c06ac8652c508e528f524a3cb747740505 100644 (file)
@@ -441,9 +441,9 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
 
                if (dev->shared_resources.enable_mes) {
                        amdgpu_amdkfd_free_gtt_mem(dev->adev,
-                                                  pqn->q->gang_ctx_bo);
+                                                  &pqn->q->gang_ctx_bo);
                        if (pqn->q->wptr_bo)
-                               amdgpu_amdkfd_free_gtt_mem(dev->adev, pqn->q->wptr_bo);
+                               amdgpu_amdkfd_free_gtt_mem(dev->adev, (void **)&pqn->q->wptr_bo);
 
                }
                uninit_queue(pqn->q);