aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3363-drm-amdkfd-Don-t-dereference-kfd_process.mm.patch
diff options
context:
space:
mode:
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.patch107
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
+