From dd7b9195a5806a96c1ab5e01e60209e5cd657124 Mon Sep 17 00:00:00 2001 From: engstk Date: Fri, 7 Jul 2023 18:14:41 +0100 Subject: [PATCH] drivers: google-modules: Merge branch android-gs-raviole-5.10-android13-qpr3 (android-13.0.0_r0.100) Signed-off-by: engstk --- .../gpu/mali_kbase/mali_kbase_mem.c | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/google-modules/gpu/mali_kbase/mali_kbase_mem.c b/drivers/google-modules/gpu/mali_kbase/mali_kbase_mem.c index ce6e94cec..776507278 100644 --- a/drivers/google-modules/gpu/mali_kbase/mali_kbase_mem.c +++ b/drivers/google-modules/gpu/mali_kbase/mali_kbase_mem.c @@ -380,6 +380,7 @@ void kbase_remove_va_region(struct kbase_device *kbdev, struct rb_node *rbnext; struct kbase_va_region *next = NULL; struct rb_root *reg_rbtree = NULL; + struct kbase_va_region *orig_reg = reg; int merged_front = 0; int merged_back = 0; @@ -477,6 +478,12 @@ void kbase_remove_va_region(struct kbase_device *kbdev, rb_replace_node(&(reg->rblink), &(free_reg->rblink), reg_rbtree); } + /* This operation is always safe because the function never frees + * the region. If the region has been merged to both front and back, + * then it's the previous region that is supposed to be freed. + */ + orig_reg->start_pfn = 0; + out: return; } @@ -1752,7 +1759,7 @@ int kbase_gpu_mmap(struct kbase_context *kctx, struct kbase_va_region *reg, reg->flags & gwt_mask, kctx->as_nr, group_id, mmu_sync_info); if (err) - goto bad_insert; + goto bad_aliased_insert; /* Note: mapping count is tracked at alias * creation time @@ -1766,7 +1773,7 @@ int kbase_gpu_mmap(struct kbase_context *kctx, struct kbase_va_region *reg, group_id, mmu_sync_info); if (err) - goto bad_insert; + goto bad_aliased_insert; } } } else { @@ -1807,10 +1814,20 @@ int kbase_gpu_mmap(struct kbase_context *kctx, struct kbase_va_region *reg, return err; -bad_insert: - kbase_mmu_teardown_pages(kctx->kbdev, &kctx->mmu, reg->start_pfn, alloc->pages, - reg->nr_pages, kctx->as_nr); +bad_aliased_insert: + while (i-- > 0) { + struct tagged_addr *phys_alloc = NULL; + u64 const stride = alloc->imported.alias.stride; + if (alloc->imported.alias.aliased[i].alloc != NULL) + phys_alloc = alloc->imported.alias.aliased[i].alloc->pages + + alloc->imported.alias.aliased[i].offset; + + kbase_mmu_teardown_pages(kctx->kbdev, &kctx->mmu, reg->start_pfn + (i * stride), + phys_alloc, alloc->imported.alias.aliased[i].length, + kctx->as_nr); + } +bad_insert: kbase_remove_va_region(kctx->kbdev, reg); return err;