diff options
| author | 2022-01-18 21:20:42 -0800 | |
|---|---|---|
| committer | 2022-01-18 21:20:42 -0800 | |
| commit | b5e83bcc7bb8d079aad8c9831e29a3597817b9d5 (patch) | |
| tree | 270b47c58f3e704fa20cd7c813f0a1a0a53cd766 | |
| parent | Merge pull request #7715 from gidoly/patch-4 (diff) | |
| parent | hle: kernel: k_memory_manager: Clear pages on allocation & free. (diff) | |
| download | yuzu-b5e83bcc7bb8d079aad8c9831e29a3597817b9d5.tar.gz yuzu-b5e83bcc7bb8d079aad8c9831e29a3597817b9d5.tar.xz yuzu-b5e83bcc7bb8d079aad8c9831e29a3597817b9d5.zip | |
Merge pull request #7701 from bunnei/clear-mem-pages
Kernel Memory Updates (Part 3): Clear KMemoryManager pages & other fixes
| -rw-r--r-- | src/core/hle/kernel/k_memory_manager.cpp | 15 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_memory_manager.h | 15 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.cpp | 17 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.h | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 2 |
5 files changed, 34 insertions, 16 deletions
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp index 0166df0a5..1b44541b1 100644 --- a/src/core/hle/kernel/k_memory_manager.cpp +++ b/src/core/hle/kernel/k_memory_manager.cpp | |||
| @@ -8,12 +8,16 @@ | |||
| 8 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "common/scope_exit.h" | 10 | #include "common/scope_exit.h" |
| 11 | #include "core/core.h" | ||
| 12 | #include "core/device_memory.h" | ||
| 11 | #include "core/hle/kernel/k_memory_manager.h" | 13 | #include "core/hle/kernel/k_memory_manager.h" |
| 12 | #include "core/hle/kernel/k_page_linked_list.h" | 14 | #include "core/hle/kernel/k_page_linked_list.h" |
| 13 | #include "core/hle/kernel/svc_results.h" | 15 | #include "core/hle/kernel/svc_results.h" |
| 14 | 16 | ||
| 15 | namespace Kernel { | 17 | namespace Kernel { |
| 16 | 18 | ||
| 19 | KMemoryManager::KMemoryManager(Core::System& system_) : system{system_} {} | ||
| 20 | |||
| 17 | std::size_t KMemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) { | 21 | std::size_t KMemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) { |
| 18 | const auto size{end_address - start_address}; | 22 | const auto size{end_address - start_address}; |
| 19 | 23 | ||
| @@ -81,7 +85,7 @@ VAddr KMemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size | |||
| 81 | } | 85 | } |
| 82 | 86 | ||
| 83 | ResultCode KMemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, | 87 | ResultCode KMemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, |
| 84 | Direction dir) { | 88 | Direction dir, u32 heap_fill_value) { |
| 85 | ASSERT(page_list.GetNumPages() == 0); | 89 | ASSERT(page_list.GetNumPages() == 0); |
| 86 | 90 | ||
| 87 | // Early return if we're allocating no pages | 91 | // Early return if we're allocating no pages |
| @@ -139,6 +143,12 @@ ResultCode KMemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_ | |||
| 139 | } | 143 | } |
| 140 | } | 144 | } |
| 141 | 145 | ||
| 146 | // Clear allocated memory. | ||
| 147 | for (const auto& it : page_list.Nodes()) { | ||
| 148 | std::memset(system.DeviceMemory().GetPointer(it.GetAddress()), heap_fill_value, | ||
| 149 | it.GetSize()); | ||
| 150 | } | ||
| 151 | |||
| 142 | // Only succeed if we allocated as many pages as we wanted | 152 | // Only succeed if we allocated as many pages as we wanted |
| 143 | if (num_pages) { | 153 | if (num_pages) { |
| 144 | return ResultOutOfMemory; | 154 | return ResultOutOfMemory; |
| @@ -146,11 +156,12 @@ ResultCode KMemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_ | |||
| 146 | 156 | ||
| 147 | // We succeeded! | 157 | // We succeeded! |
| 148 | group_guard.Cancel(); | 158 | group_guard.Cancel(); |
| 159 | |||
| 149 | return ResultSuccess; | 160 | return ResultSuccess; |
| 150 | } | 161 | } |
| 151 | 162 | ||
| 152 | ResultCode KMemoryManager::Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, | 163 | ResultCode KMemoryManager::Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, |
| 153 | Direction dir) { | 164 | Direction dir, u32 heap_fill_value) { |
| 154 | // Early return if we're freeing no pages | 165 | // Early return if we're freeing no pages |
| 155 | if (!num_pages) { | 166 | if (!num_pages) { |
| 156 | return ResultSuccess; | 167 | return ResultSuccess; |
diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h index 39badc5f1..abd6c8ace 100644 --- a/src/core/hle/kernel/k_memory_manager.h +++ b/src/core/hle/kernel/k_memory_manager.h | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | #include "core/hle/kernel/k_page_heap.h" | 12 | #include "core/hle/kernel/k_page_heap.h" |
| 13 | #include "core/hle/result.h" | 13 | #include "core/hle/result.h" |
| 14 | 14 | ||
| 15 | namespace Core { | ||
| 16 | class System; | ||
| 17 | } | ||
| 18 | |||
| 15 | namespace Kernel { | 19 | namespace Kernel { |
| 16 | 20 | ||
| 17 | class KPageLinkedList; | 21 | class KPageLinkedList; |
| @@ -42,7 +46,7 @@ public: | |||
| 42 | Mask = (0xF << Shift), | 46 | Mask = (0xF << Shift), |
| 43 | }; | 47 | }; |
| 44 | 48 | ||
| 45 | KMemoryManager() = default; | 49 | explicit KMemoryManager(Core::System& system_); |
| 46 | 50 | ||
| 47 | constexpr std::size_t GetSize(Pool pool) const { | 51 | constexpr std::size_t GetSize(Pool pool) const { |
| 48 | return managers[static_cast<std::size_t>(pool)].GetSize(); | 52 | return managers[static_cast<std::size_t>(pool)].GetSize(); |
| @@ -51,10 +55,10 @@ public: | |||
| 51 | void InitializeManager(Pool pool, u64 start_address, u64 end_address); | 55 | void InitializeManager(Pool pool, u64 start_address, u64 end_address); |
| 52 | 56 | ||
| 53 | VAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); | 57 | VAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); |
| 54 | ResultCode Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, | 58 | ResultCode Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, Direction dir, |
| 55 | Direction dir = Direction::FromFront); | 59 | u32 heap_fill_value = 0); |
| 56 | ResultCode Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, | 60 | ResultCode Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, Direction dir, |
| 57 | Direction dir = Direction::FromFront); | 61 | u32 heap_fill_value = 0); |
| 58 | 62 | ||
| 59 | static constexpr std::size_t MaxManagerCount = 10; | 63 | static constexpr std::size_t MaxManagerCount = 10; |
| 60 | 64 | ||
| @@ -129,6 +133,7 @@ private: | |||
| 129 | }; | 133 | }; |
| 130 | 134 | ||
| 131 | private: | 135 | private: |
| 136 | Core::System& system; | ||
| 132 | std::array<std::mutex, static_cast<std::size_t>(Pool::Count)> pool_locks; | 137 | std::array<std::mutex, static_cast<std::size_t>(Pool::Count)> pool_locks; |
| 133 | std::array<Impl, MaxManagerCount> managers; | 138 | std::array<Impl, MaxManagerCount> managers; |
| 134 | }; | 139 | }; |
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 27d86c9a4..b650ea31d 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -289,8 +289,8 @@ ResultCode KPageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemory | |||
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | KPageLinkedList page_linked_list; | 291 | KPageLinkedList page_linked_list; |
| 292 | CASCADE_CODE( | 292 | CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool, |
| 293 | system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); | 293 | allocation_option)); |
| 294 | CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)); | 294 | CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)); |
| 295 | 295 | ||
| 296 | block_manager->Update(addr, num_pages, state, perm); | 296 | block_manager->Update(addr, num_pages, state, perm); |
| @@ -457,8 +457,8 @@ ResultCode KPageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 457 | 457 | ||
| 458 | KPageLinkedList page_linked_list; | 458 | KPageLinkedList page_linked_list; |
| 459 | 459 | ||
| 460 | CASCADE_CODE( | 460 | CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, |
| 461 | system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, memory_pool)); | 461 | memory_pool, allocation_option)); |
| 462 | 462 | ||
| 463 | // We succeeded, so commit the memory reservation. | 463 | // We succeeded, so commit the memory reservation. |
| 464 | memory_reservation.Commit(); | 464 | memory_reservation.Commit(); |
| @@ -541,7 +541,8 @@ ResultCode KPageTable::UnmapMemory(VAddr addr, std::size_t size) { | |||
| 541 | } | 541 | } |
| 542 | 542 | ||
| 543 | const std::size_t num_pages{size / PageSize}; | 543 | const std::size_t num_pages{size / PageSize}; |
| 544 | system.Kernel().MemoryManager().Free(page_linked_list, num_pages, memory_pool); | 544 | system.Kernel().MemoryManager().Free(page_linked_list, num_pages, memory_pool, |
| 545 | allocation_option); | ||
| 545 | 546 | ||
| 546 | block_manager->Update(addr, num_pages, KMemoryState::Free); | 547 | block_manager->Update(addr, num_pages, KMemoryState::Free); |
| 547 | 548 | ||
| @@ -960,7 +961,7 @@ ResultCode KPageTable::SetHeapSize(VAddr* out, std::size_t size) { | |||
| 960 | // Allocate pages for the heap extension. | 961 | // Allocate pages for the heap extension. |
| 961 | KPageLinkedList page_linked_list; | 962 | KPageLinkedList page_linked_list; |
| 962 | R_TRY(system.Kernel().MemoryManager().Allocate(page_linked_list, allocation_size / PageSize, | 963 | R_TRY(system.Kernel().MemoryManager().Allocate(page_linked_list, allocation_size / PageSize, |
| 963 | memory_pool)); | 964 | memory_pool, allocation_option)); |
| 964 | 965 | ||
| 965 | // Map the pages. | 966 | // Map the pages. |
| 966 | { | 967 | { |
| @@ -1027,8 +1028,8 @@ ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages, | |||
| 1027 | CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); | 1028 | CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); |
| 1028 | } else { | 1029 | } else { |
| 1029 | KPageLinkedList page_group; | 1030 | KPageLinkedList page_group; |
| 1030 | CASCADE_CODE( | 1031 | CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, |
| 1031 | system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, memory_pool)); | 1032 | memory_pool, allocation_option)); |
| 1032 | CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)); | 1033 | CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)); |
| 1033 | } | 1034 | } |
| 1034 | 1035 | ||
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 274644181..f67986e91 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -303,6 +303,7 @@ private: | |||
| 303 | bool is_aslr_enabled{}; | 303 | bool is_aslr_enabled{}; |
| 304 | 304 | ||
| 305 | KMemoryManager::Pool memory_pool{KMemoryManager::Pool::Application}; | 305 | KMemoryManager::Pool memory_pool{KMemoryManager::Pool::Application}; |
| 306 | KMemoryManager::Direction allocation_option{KMemoryManager::Direction::FromFront}; | ||
| 306 | 307 | ||
| 307 | Common::PageTable page_table_impl; | 308 | Common::PageTable page_table_impl; |
| 308 | 309 | ||
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index e5cf9abb3..887c1fd27 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -631,7 +631,7 @@ struct KernelCore::Impl { | |||
| 631 | const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents(); | 631 | const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents(); |
| 632 | 632 | ||
| 633 | // Initialize memory managers | 633 | // Initialize memory managers |
| 634 | memory_manager = std::make_unique<KMemoryManager>(); | 634 | memory_manager = std::make_unique<KMemoryManager>(system); |
| 635 | memory_manager->InitializeManager(KMemoryManager::Pool::Application, | 635 | memory_manager->InitializeManager(KMemoryManager::Pool::Application, |
| 636 | application_pool.GetAddress(), | 636 | application_pool.GetAddress(), |
| 637 | application_pool.GetEndAddress()); | 637 | application_pool.GetEndAddress()); |