diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3363-drm-amdkfd-Don-t-dereference-kfd_process.mm.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3363-drm-amdkfd-Don-t-dereference-kfd_process.mm.patch | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3363-drm-amdkfd-Don-t-dereference-kfd_process.mm.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3363-drm-amdkfd-Don-t-dereference-kfd_process.mm.patch new file mode 100644 index 00000000..2c6571b5 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3363-drm-amdkfd-Don-t-dereference-kfd_process.mm.patch @@ -0,0 +1,107 @@ +From 4f7cfff21692e7ad9bfd664520a0ceb6fbda010e Mon Sep 17 00:00:00 2001 +From: Felix Kuehling <Felix.Kuehling@amd.com> +Date: Fri, 27 Oct 2017 19:35:19 -0400 +Subject: [PATCH 3363/4131] drm/amdkfd: Don't dereference kfd_process.mm + +The kfd_process doesn't own a reference to the mm_struct, so it can +disappear without warning even while the kfd_process still exists. + +Therefore, avoid dereferencing the kfd_process.mm pointer and make +it opaque. Use get_task_mm to get a temporary reference to the mm +when it's needed. + +v2: removed unnecessary WARN_ON + +Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> +Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com> +Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com> +--- + drivers/gpu/drm/amd/amdkfd/kfd_events.c | 19 +++++++++++++++---- + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 7 ++++++- + drivers/gpu/drm/amd/amdkfd/kfd_process.c | 1 - + 3 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c +index 944abfa..61ce547 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c +@@ -24,8 +24,8 @@ + #include <linux/slab.h> + #include <linux/types.h> + #include <linux/sched/signal.h> ++#include <linux/sched/mm.h> + #include <linux/uaccess.h> +-#include <linux/mm.h> + #include <linux/mman.h> + #include <linux/memory.h> + #include "kfd_priv.h" +@@ -904,14 +904,24 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, unsigned int pasid, + * running so the lookup function returns a locked process. + */ + struct kfd_process *p = kfd_lookup_process_by_pasid(pasid); ++ struct mm_struct *mm; + + if (!p) + return; /* Presumably process exited. */ + ++ /* Take a safe reference to the mm_struct, which may otherwise ++ * disappear even while the kfd_process is still referenced. ++ */ ++ mm = get_task_mm(p->lead_thread); ++ if (!mm) { ++ mutex_unlock(&p->mutex); ++ return; /* Process is exiting */ ++ } ++ + memset(&memory_exception_data, 0, sizeof(memory_exception_data)); + +- down_read(&p->mm->mmap_sem); +- vma = find_vma(p->mm, address); ++ down_read(&mm->mmap_sem); ++ vma = find_vma(mm, address); + + memory_exception_data.gpu_id = dev->id; + memory_exception_data.va = address; +@@ -937,7 +947,8 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, unsigned int pasid, + } + } + +- up_read(&p->mm->mmap_sem); ++ up_read(&mm->mmap_sem); ++ mmput(mm); + + mutex_lock(&p->event_mutex); + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +index 7d86ec9..1a483a7 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +@@ -494,7 +494,12 @@ struct kfd_process { + */ + struct hlist_node kfd_processes; + +- struct mm_struct *mm; ++ /* ++ * Opaque pointer to mm_struct. We don't hold a reference to ++ * it so it should never be dereferenced from here. This is ++ * only used for looking up processes by their mm. ++ */ ++ void *mm; + + struct mutex mutex; + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c +index 3ccb3b5..695fa2a 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c +@@ -200,7 +200,6 @@ static void kfd_process_destroy_delayed(struct rcu_head *rcu) + struct kfd_process *p; + + p = container_of(rcu, struct kfd_process, rcu); +- WARN_ON(atomic_read(&p->mm->mm_count) <= 0); + + mmdrop(p->mm); + +-- +2.7.4 + |