From 330843f54465ee9b62e1a1e2f6c5d12b14c3b548 Mon Sep 17 00:00:00 2001 From: Lynus Vaz Date: Mon, 27 Nov 2023 06:53:01 -0800 Subject: [PATCH] msm: kgsl: Do not free sharedmem if it cannot be unmapped If sharedmem cannot be unmapped from the mmu, it can still be accessed by the GPU. Therefore it is not safe to free the backing memory. In the case that unmap fails, do not free it or return it to the system. Change-Id: Iad3e86d043f129a4d71cf862865d9033d4a315e3 Signed-off-by: Lynus Vaz --- drivers/gpu/msm/kgsl_mmu.c | 2 ++ drivers/gpu/msm/kgsl_sharedmem.c | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index 2633b72f18f7..33fcaabf838d 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -483,6 +483,8 @@ kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, size = kgsl_memdesc_footprint(memdesc); ret = pagetable->pt_ops->mmu_unmap(pagetable, memdesc); + if (ret) + return ret; atomic_dec(&pagetable->stats.entries); atomic_long_sub(size, &pagetable->stats.mapped); diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index ae66f3acba30..d77ec299ae04 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -948,6 +949,9 @@ static void kgsl_contiguous_free(struct kgsl_memdesc *memdesc) if (!memdesc->hostptr) return; + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + atomic_long_sub(memdesc->size, &kgsl_driver.stats.coherent); #ifdef CONFIG_MM_STAT_UNRECLAIMABLE_PAGES @@ -963,9 +967,14 @@ static void kgsl_free_secure_system_pages(struct kgsl_memdesc *memdesc) { int i; struct scatterlist *sg; - int ret = unlock_sgt(memdesc->sgt); + int ret; int order = get_order(PAGE_SIZE); + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + + ret = unlock_sgt(memdesc->sgt); + if (ret) { /* * Unlock of the secure buffer failed. This buffer will @@ -998,7 +1007,12 @@ static void kgsl_free_secure_system_pages(struct kgsl_memdesc *memdesc) static void kgsl_free_secure_pool_pages(struct kgsl_memdesc *memdesc) { - int ret = unlock_sgt(memdesc->sgt); + int ret; + + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + + ret = unlock_sgt(memdesc->sgt); if (ret) { /* @@ -1028,6 +1042,9 @@ static void kgsl_free_pool_pages(struct kgsl_memdesc *memdesc) kgsl_paged_unmap_kernel(memdesc); WARN_ON(memdesc->hostptr); + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + atomic_long_sub(memdesc->size, &kgsl_driver.stats.page_alloc); kgsl_pool_free_pages(memdesc->pages, memdesc->page_count); @@ -1045,6 +1062,9 @@ static void kgsl_free_system_pages(struct kgsl_memdesc *memdesc) kgsl_paged_unmap_kernel(memdesc); WARN_ON(memdesc->hostptr); + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + atomic_long_sub(memdesc->size, &kgsl_driver.stats.page_alloc); for (i = 0; i < memdesc->page_count; i++) {