diff options
author | Akash Goel <akash.goel@arm.com> | 2022-01-04 08:44:41 +0000 |
---|---|---|
committer | Sean Callanan <spyffe@google.com> | 2022-01-12 22:32:00 +0000 |
commit | 5381ff7b4106b277ff207396e293ede2bf959f0c (patch) | |
tree | 70a47851ce0062ea713ab934a8910c96085ecb96 /mali_kbase/mali_kbase_mem.c | |
parent | 15ef09a50229e10d8836b75b59c0a69e6459692d (diff) | |
download | gpu-5381ff7b4106b277ff207396e293ede2bf959f0c.tar.gz |
GPUCORE-32592 Fix userbuf imports to respect RO memoryandroid-t-preview-1_r0.4android-gs-raviole-5.10-t-preview-1
Fix the pinning stage of userbuf imports to correctly respect RO memory
for both CPU and GPU write access, not just GPU access.
Hence, a userbuf that is read-write at import time but then read-only at
map time (by munmap() and then mmap() a different mapping at exactly the
same address) will properly respect the read-only permissions.
In addition, ensure we mark the pages as dirty for both CPU writes as
well as GPU writes.
Signed-off-by: Sean Callanan <spyffe@google.com>
Change-Id: I3eb899277705b82aa344355cd1d2cd5f343ccfff
Diffstat (limited to 'mali_kbase/mali_kbase_mem.c')
-rw-r--r-- | mali_kbase/mali_kbase_mem.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/mali_kbase/mali_kbase_mem.c b/mali_kbase/mali_kbase_mem.c index 4b9721f..a2407a0 100644 --- a/mali_kbase/mali_kbase_mem.c +++ b/mali_kbase/mali_kbase_mem.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note /* * - * (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved. + * (C) COPYRIGHT 2010-2022 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software @@ -1683,7 +1683,8 @@ int kbase_gpu_munmap(struct kbase_context *kctx, struct kbase_va_region *reg) /* The allocation could still have active mappings. */ if (user_buf->current_mapping_usage_count == 0) { kbase_jd_user_buf_unmap(kctx, reg->gpu_alloc, - (reg->flags & KBASE_REG_GPU_WR)); + (reg->flags & (KBASE_REG_CPU_WR | + KBASE_REG_GPU_WR))); } } } @@ -4561,6 +4562,7 @@ int kbase_jd_user_buf_pin_pages(struct kbase_context *kctx, struct mm_struct *mm = alloc->imported.user_buf.mm; long pinned_pages; long i; + int write; if (WARN_ON(alloc->type != KBASE_MEM_TYPE_IMPORTED_USER_BUF)) return -EINVAL; @@ -4575,41 +4577,37 @@ int kbase_jd_user_buf_pin_pages(struct kbase_context *kctx, if (WARN_ON(reg->gpu_alloc->imported.user_buf.mm != current->mm)) return -EINVAL; + write = reg->flags & (KBASE_REG_CPU_WR | KBASE_REG_GPU_WR); + #if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE - pinned_pages = get_user_pages(NULL, mm, - address, - alloc->imported.user_buf.nr_pages, + pinned_pages = get_user_pages( + NULL, mm, address, + alloc->imported.user_buf.nr_pages, #if KERNEL_VERSION(4, 4, 168) <= LINUX_VERSION_CODE && \ KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE - reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0, - pages, NULL); + write ? FOLL_WRITE : 0, pages, NULL); #else - reg->flags & KBASE_REG_GPU_WR, - 0, pages, NULL); + write, 0, pages, NULL); #endif #elif KERNEL_VERSION(4, 9, 0) > LINUX_VERSION_CODE - pinned_pages = get_user_pages_remote(NULL, mm, - address, - alloc->imported.user_buf.nr_pages, - reg->flags & KBASE_REG_GPU_WR, - 0, pages, NULL); + pinned_pages = get_user_pages_remote( + NULL, mm, + address, alloc->imported.user_buf.nr_pages, + write, 0, pages, NULL); #elif KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE - pinned_pages = get_user_pages_remote(NULL, mm, - address, - alloc->imported.user_buf.nr_pages, - reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0, - pages, NULL); + pinned_pages = get_user_pages_remote( + NULL, mm, + address, alloc->imported.user_buf.nr_pages, + write ? FOLL_WRITE : 0, pages, NULL); #elif KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE - pinned_pages = get_user_pages_remote(NULL, mm, - address, - alloc->imported.user_buf.nr_pages, - reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0, - pages, NULL, NULL); + pinned_pages = get_user_pages_remote( + NULL, mm, + address, alloc->imported.user_buf.nr_pages, + write ? FOLL_WRITE : 0, pages, NULL, NULL); #else pinned_pages = pin_user_pages_remote( mm, address, alloc->imported.user_buf.nr_pages, - reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0, pages, NULL, - NULL); + write ? FOLL_WRITE : 0, pages, NULL, NULL); #endif if (pinned_pages <= 0) @@ -4843,7 +4841,7 @@ void kbase_unmap_external_resource(struct kbase_context *kctx, kbase_reg_current_backed_size(reg), kctx->as_nr); - if (reg && ((reg->flags & KBASE_REG_GPU_WR) == 0)) + if (reg && ((reg->flags & (KBASE_REG_CPU_WR | KBASE_REG_GPU_WR)) == 0)) writeable = false; kbase_jd_user_buf_unmap(kctx, alloc, writeable); |