diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/1583-drm-amdgpu-Fix-userptr-restore-race-condition-with-f.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/1583-drm-amdgpu-Fix-userptr-restore-race-condition-with-f.patch | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/1583-drm-amdgpu-Fix-userptr-restore-race-condition-with-f.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/1583-drm-amdgpu-Fix-userptr-restore-race-condition-with-f.patch new file mode 100644 index 00000000..e89712ba --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/1583-drm-amdgpu-Fix-userptr-restore-race-condition-with-f.patch @@ -0,0 +1,84 @@ +From 2c3b0f1e194a27c0c51703e8b9c6ed5356a06944 Mon Sep 17 00:00:00 2001 +From: Felix Kuehling <Felix.Kuehling@amd.com> +Date: Fri, 3 Feb 2017 17:50:59 -0500 +Subject: [PATCH 1583/4131] drm/amdgpu: Fix userptr restore race condition with + free + +Update_user_pages needs to drop the lock. This could lead to freeing +a userptr BO while a restore was in progress. In that case +cancel_restore_locked and restore_mem_worker would both call mmput +and lead to corruption of kernel data structures. + +Fix this by marking the mem object as busy while dropping the lock +for user page udpates. When canceling restore, wait for busy mem +objects. This ensures that a restore that has already started will +be able complete before the BO gets freed. When the restore completes +it sets mem->mm to NULL and calls mmput. Thes cancel_restore_locked +will not call mmput again. + +Bug: SWDEV-112697 +Change-Id: I6c76f7559957992303cf69b7a26360886f090990 +Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 11 +++++++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 ++ + 3 files changed, 14 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +index 05a627a..a2d1b55 100755 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +@@ -194,6 +194,17 @@ static void cancel_restore_locked(struct kgd_mem *mem) + struct mm_struct *mm; + + while (mem->mm) { ++ /* update_user_pages needs to drop the lock ++ * briefly. Therefore holding the lock is no guarantee ++ * that no restore is in progress ++ */ ++ if (mem->busy) { ++ mutex_unlock(&mem->lock); ++ schedule_timeout_uninterruptible(1); ++ mutex_lock(&mem->lock); ++ continue; ++ } ++ + mm = mem->mm; + mem->mm = NULL; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +index 9ac3b6b..db4f75c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +@@ -63,6 +63,7 @@ struct kgd_mem { + /* flags bitfield */ + bool no_substitute : 1; + bool aql_queue : 1; ++ bool busy : 1; + }; + + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +index d08d25c6..8d05564 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +@@ -826,6 +826,7 @@ static int update_user_pages(struct kgd_mem *mem, struct mm_struct *mm, + if (!pages) + return -ENOMEM; + ++ mem->busy = true; + mutex_unlock(&mem->lock); + + while (true) { +@@ -834,6 +835,7 @@ static int update_user_pages(struct kgd_mem *mem, struct mm_struct *mm, + up_read(&mm->mmap_sem); + + mutex_lock(&mem->lock); ++ mem->busy = false; + if (ret != 0) + return ret; + +-- +2.7.4 + |