summaryrefslogtreecommitdiff
path: root/mali_kbase/context
diff options
context:
space:
mode:
authorSuzanne Candanedo <suzanne.candanedo@arm.com>2023-04-12 11:53:49 +0100
committerGuus Sliepen <gsliepen@google.com>2023-08-07 19:14:44 +0000
commitca522e4491584d5a2a5f122ee90e3edb3581182b (patch)
treece53ef0fc291fea44cc7583f2d63d54592314b60 /mali_kbase/context
parente56f5663a2b589c2cc96ab52c23781d500dfcace (diff)
downloadgpu-ca522e4491584d5a2a5f122ee90e3edb3581182b.tar.gz
Kbase accounts the GPU memory allocated for a context under the memory footprint of a process, so that kernel's low memory killer or OoM killer can kill the suitable process to free up decent amount of system memory. For accounting, Kbase updates the 'MM_FILEPAGES' counter inside the 'mm_struct' corresponding to the process that created the Kbase context. To ensure 'mm_struct' can always be safely accessed, a tracking page was used which Kbase mandated to be mapped right after the opening of '/dev/mali0' file. When the mapping was closed Kbase updated the kernel counter to subtract all the GPU memory allocated so far for a context but the actual freeing of GPU memory was done later. This was usually not a problem as the mapping is closed by DDK Userspace just before the context termination. But the Userspace is allowed to close it at will. Malicious Userspace could have exploited this Kbase quirk by closing the mapping which would have mislead the OoM killer in killing the innocent processes before it gets around to the culprit process. This commit removes the use of tracking page and uses mmgrab() to take a reference on 'mm_struct' for User created Kbase context. The reference doesn't prevent the freeing of address space on process exit, it merely keeps the 'mm_struct' alive. The reference is dropped on context termination. For backward compatibility, the call from Base to create the mapping for tracking page isn't rejected by Kbase. The Base code has been updated to skip the mapping of tracking page only for newer Kbase so as to maintain forward compatibility with the older Kbase. BASE_UK_VERSION_MINOR has been incremented as the requirement to create a mapping for tracking page is relaxed by Kbase. Change-Id: I37407809d7187cb5c8fac63e6c10f72cc3bd762d Bug: 275853921 Provenance: https://code.ipdelivery.arm.com/c/GPU/mali-ddk/+/5165 (cherry picked from commit b29f4a639e0863c09e72d7e34c0a6ad57f9572a6)
Diffstat (limited to 'mali_kbase/context')
-rw-r--r--mali_kbase/context/mali_kbase_context.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/mali_kbase/context/mali_kbase_context.c b/mali_kbase/context/mali_kbase_context.c
index 8787a56..7dece16 100644
--- a/mali_kbase/context/mali_kbase_context.c
+++ b/mali_kbase/context/mali_kbase_context.c
@@ -182,7 +182,6 @@ int kbase_context_common_init(struct kbase_context *kctx)
/* creating a context is considered a disjoint event */
kbase_disjoint_event(kctx->kbdev);
- spin_lock_init(&kctx->mm_update_lock);
kctx->process_mm = NULL;
kctx->task = NULL;
atomic_set(&kctx->nonmapped_pages, 0);
@@ -223,6 +222,13 @@ int kbase_context_common_init(struct kbase_context *kctx)
if (unlikely(err))
return err;
+
+ /* This merely takes a reference on the mm_struct and not on the
+ * address space and so won't block the freeing of address space
+ * on process exit.
+ */
+ mmgrab(current->mm);
+ kctx->process_mm = current->mm;
}
atomic_set(&kctx->used_pages, 0);
@@ -256,14 +262,18 @@ int kbase_context_common_init(struct kbase_context *kctx)
mutex_lock(&kctx->kbdev->kctx_list_lock);
err = kbase_insert_kctx_to_process(kctx);
- mutex_unlock(&kctx->kbdev->kctx_list_lock);
+
if (err) {
dev_err(kctx->kbdev->dev,
"(err:%d) failed to insert kctx to kbase_process", err);
- if (likely(kctx->filp))
+ if (likely(kctx->filp)) {
put_task_struct(kctx->task);
+ mmdrop(kctx->process_mm);
+ }
}
+ mutex_unlock(&kctx->kbdev->kctx_list_lock);
+
return err;
}
@@ -350,8 +360,10 @@ void kbase_context_common_term(struct kbase_context *kctx)
kbase_remove_kctx_from_process(kctx);
mutex_unlock(&kctx->kbdev->kctx_list_lock);
- if (likely(kctx->filp))
+ if (likely(kctx->filp)) {
put_task_struct(kctx->task);
+ mmdrop(kctx->process_mm);
+ }
KBASE_KTRACE_ADD(kctx->kbdev, CORE_CTX_DESTROY, kctx, 0u);
}