diff --git a/drivers/video/tegra/nvmap/nvmap_core.c b/drivers/video/tegra/nvmap/nvmap_core.c index 4d555f04..a24ae13a 100644 --- a/drivers/video/tegra/nvmap/nvmap_core.c +++ b/drivers/video/tegra/nvmap/nvmap_core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * SPDX-FileCopyrightText: Copyright (c) 2009-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-FileCopyrightText: Copyright (c) 2009-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * Memory manager for Tegra GPU */ @@ -96,7 +96,9 @@ void *__nvmap_mmap(struct nvmap_handle *h) /* carveout - explicitly map the pfns into a vmalloc area */ adj_size = nvmap_get_heap_block_base(h->carveout) & ~PAGE_MASK; - adj_size += h->size; + if (check_add_overflow(adj_size, h->size, &adj_size)) + goto dec_kmaps; + adj_size = PAGE_ALIGN(adj_size); if (pfn_valid(__phys_to_pfn(nvmap_get_heap_block_base(h->carveout) & PAGE_MASK))) { @@ -149,6 +151,7 @@ void *__nvmap_mmap(struct nvmap_handle *h) out: if (pages) vfree(pages); +dec_kmaps: nvmap_kmaps_dec(h); put_handle: nvmap_handle_put(h); diff --git a/drivers/video/tegra/nvmap/nvmap_debug.c b/drivers/video/tegra/nvmap/nvmap_debug.c index 5defd115..94d0c97d 100644 --- a/drivers/video/tegra/nvmap/nvmap_debug.c +++ b/drivers/video/tegra/nvmap/nvmap_debug.c @@ -297,7 +297,7 @@ static int nvmap_page_mapcount(struct page *page) } #define PSS_SHIFT 12 -static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id) +static int nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id) { int i; struct rb_node *n; @@ -307,7 +307,7 @@ static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id if (pss) *pss = 0; if (dev == NULL) - return; + return 0; spin_lock(&dev->handle_lock); n = rb_first(&dev->handles); for (; n != NULL; n = rb_next(n)) { @@ -322,18 +322,28 @@ static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id numa_id)) continue; - *total += h->size; + if (check_add_overflow(*total, (u64)h->size, &*total)) { + spin_unlock(&dev->handle_lock); + return -EOVERFLOW; + } + if (!pss) continue; for (i = 0; i < h->size >> PAGE_SHIFT; i++) { struct page *page = nvmap_to_page(h->pgalloc.pages[i]); - if (nvmap_page_mapcount(page) > 0) - *pss += PAGE_SIZE; + if (nvmap_page_mapcount(page) > 0) { + if (check_add_overflow(*pss, (u64)PAGE_SIZE, &*pss)) { + spin_unlock(&dev->handle_lock); + return -EOVERFLOW; + } + + } } } spin_unlock(&dev->handle_lock); + return 0; } static int nvmap_debug_allocations_show(struct seq_file *s, void *unused) @@ -365,7 +375,10 @@ static int nvmap_debug_allocations_show(struct seq_file *s, void *unused) seq_puts(s, "\n"); } mutex_unlock(&nvmap_dev->clients_lock); - nvmap_get_total_mss(NULL, &total, heap_type, numa_id); + err = nvmap_get_total_mss(NULL, &total, heap_type, numa_id); + if (err != 0) + return err; + seq_printf(s, "%-18s %-18s %8s %10lluK\n", "total", "", "", K(total)); return 0; } @@ -581,7 +594,10 @@ static int nvmap_debug_maps_show(struct seq_file *s, void *unused) } mutex_unlock(&nvmap_dev->clients_lock); - nvmap_get_total_mss(NULL, &total, heap_type, numa_id); + err = nvmap_get_total_mss(NULL, &total, heap_type, numa_id); + if (err != 0) + return err; + seq_printf(s, "%-18s %-18s %8s %10lluK\n", "total", "", "", K(total)); return 0; } @@ -612,7 +628,10 @@ static int nvmap_debug_clients_show(struct seq_file *s, void *unused) seq_printf(s, " %10lluK\n", K(client_total)); } mutex_unlock(&nvmap_dev->clients_lock); - nvmap_get_total_mss(NULL, &total, heap_type, numa_id); + err = nvmap_get_total_mss(NULL, &total, heap_type, numa_id); + if (err != 0) + return err; + seq_printf(s, "%-18s %18s %8s %10lluK\n", "total", "", "", K(total)); return 0; } @@ -833,7 +852,10 @@ static int nvmap_debug_iovmm_procrank_show(struct seq_file *s, void *unused) } mutex_unlock(&dev->clients_lock); - nvmap_get_total_mss(&total_pss, &total_memory, NVMAP_HEAP_IOVMM, NUMA_NO_NODE); + err = nvmap_get_total_mss(&total_pss, &total_memory, NVMAP_HEAP_IOVMM, NUMA_NO_NODE); + if (err != 0) + return err; + seq_printf(s, "%-18s %18s %8s %10lluK %10lluK\n", "total", "", "", K(total_pss), K(total_memory)); return 0;