From 94ac457ce010baca42863e7b1c95128c083756a5 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sun, 29 Jan 2023 22:18:31 +0000 Subject: [PATCH] Ensure mappings are always aligned to big page size when deallocated and mapped Since we align up when allocating, not doing so when deallocating would result in a gradual buildup of boundary pages that eventually fill the whole address space. --- .../skyline/services/nvdrv/devices/nvhost/as_gpu.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/as_gpu.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/as_gpu.cpp index 9f013762..5672737b 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/as_gpu.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/as_gpu.cpp @@ -93,8 +93,9 @@ namespace skyline::service::nvdrv::device::nvhost { if (!mapping->fixed) { auto &allocator{mapping->bigPage ? *vm.bigPageAllocator : *vm.smallPageAllocator}; u32 pageSizeBits{mapping->bigPage ? vm.bigPageSizeBits : VM::PageSizeBits}; + u32 pageSize{mapping->bigPage ? vm.bigPageSize : VM::PageSize}; - allocator.Free(static_cast(mapping->offset >> pageSizeBits), static_cast(mapping->size >> pageSizeBits)); + allocator.Free(static_cast(mapping->offset >> pageSizeBits), static_cast(util::AlignUp(mapping->size, pageSize) >> pageSizeBits)); } // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state @@ -128,8 +129,9 @@ namespace skyline::service::nvdrv::device::nvhost { if (allocation.sparse) asCtx->gmmu.Unmap(offset, allocation.size); - auto &allocator{pageSize == VM::PageSize ? *vm.smallPageAllocator : *vm.bigPageAllocator}; - u32 pageSizeBits{pageSize == VM::PageSize ? VM::PageSizeBits : vm.bigPageSizeBits}; + bool bigPage{pageSize != VM::PageSize}; + auto &allocator{bigPage ? *vm.bigPageAllocator : *vm.smallPageAllocator}; + u32 pageSizeBits{bigPage ? vm.bigPageSizeBits : VM::PageSizeBits}; allocator.Free(static_cast(offset >> pageSizeBits), static_cast(allocation.size >> pageSizeBits)); allocationMap.erase(offset); @@ -226,7 +228,7 @@ namespace skyline::service::nvdrv::device::nvhost { if (!offset) throw exception("Failed to allocate free space in the GPU AS!"); - asCtx->gmmu.Map(offset, cpuPtr, size); + asCtx->gmmu.Map(offset, cpuPtr, util::AlignUp(size, pageSize)); auto mapping{std::make_shared(cpuPtr, offset, size, false, bigPage, false)}; mappingMap[offset] = mapping;