diff options
| author | 2024-01-01 13:56:16 -0600 | |
|---|---|---|
| committer | 2024-01-01 13:56:16 -0600 | |
| commit | f0f92edbd0a78abda819251ddc325da4acc14216 (patch) | |
| tree | 6a23c1be26148c4137a6f67ebdf926a3f82ce47f /src/core/hle/kernel | |
| parent | Merge pull request #12501 from liamwhite/ips (diff) | |
| parent | heap_tracker: use linear-time mapping eviction (diff) | |
| download | yuzu-f0f92edbd0a78abda819251ddc325da4acc14216.tar.gz yuzu-f0f92edbd0a78abda819251ddc325da4acc14216.tar.xz yuzu-f0f92edbd0a78abda819251ddc325da4acc14216.zip | |
Merge pull request #12466 from liamwhite/sh2
core: track separate heap allocation for linux
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/k_page_table_base.cpp | 26 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table_base.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 6 |
3 files changed, 23 insertions, 12 deletions
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 423289145..8c1549559 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp | |||
| @@ -434,7 +434,7 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool | |||
| 434 | void KPageTableBase::Finalize() { | 434 | void KPageTableBase::Finalize() { |
| 435 | auto HostUnmapCallback = [&](KProcessAddress addr, u64 size) { | 435 | auto HostUnmapCallback = [&](KProcessAddress addr, u64 size) { |
| 436 | if (Settings::IsFastmemEnabled()) { | 436 | if (Settings::IsFastmemEnabled()) { |
| 437 | m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size); | 437 | m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size, false); |
| 438 | } | 438 | } |
| 439 | }; | 439 | }; |
| 440 | 440 | ||
| @@ -5243,7 +5243,7 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) { | |||
| 5243 | // Unmap. | 5243 | // Unmap. |
| 5244 | R_ASSERT(this->Operate(updater.GetPageList(), cur_address, | 5244 | R_ASSERT(this->Operate(updater.GetPageList(), cur_address, |
| 5245 | cur_pages, 0, false, unmap_properties, | 5245 | cur_pages, 0, false, unmap_properties, |
| 5246 | OperationType::Unmap, true)); | 5246 | OperationType::UnmapPhysical, true)); |
| 5247 | } | 5247 | } |
| 5248 | 5248 | ||
| 5249 | // Check if we're done. | 5249 | // Check if we're done. |
| @@ -5326,7 +5326,7 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) { | |||
| 5326 | // Map the papges. | 5326 | // Map the papges. |
| 5327 | R_TRY(this->Operate(updater.GetPageList(), cur_address, map_pages, | 5327 | R_TRY(this->Operate(updater.GetPageList(), cur_address, map_pages, |
| 5328 | cur_pg, map_properties, | 5328 | cur_pg, map_properties, |
| 5329 | OperationType::MapFirstGroup, false)); | 5329 | OperationType::MapFirstGroupPhysical, false)); |
| 5330 | } | 5330 | } |
| 5331 | } | 5331 | } |
| 5332 | 5332 | ||
| @@ -5480,7 +5480,7 @@ Result KPageTableBase::UnmapPhysicalMemory(KProcessAddress address, size_t size) | |||
| 5480 | 5480 | ||
| 5481 | // Unmap. | 5481 | // Unmap. |
| 5482 | R_ASSERT(this->Operate(updater.GetPageList(), cur_address, cur_pages, 0, false, | 5482 | R_ASSERT(this->Operate(updater.GetPageList(), cur_address, cur_pages, 0, false, |
| 5483 | unmap_properties, OperationType::Unmap, false)); | 5483 | unmap_properties, OperationType::UnmapPhysical, false)); |
| 5484 | } | 5484 | } |
| 5485 | 5485 | ||
| 5486 | // Check if we're done. | 5486 | // Check if we're done. |
| @@ -5655,7 +5655,10 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5655 | // or free them to the page list, and so it goes unused (along with page properties). | 5655 | // or free them to the page list, and so it goes unused (along with page properties). |
| 5656 | 5656 | ||
| 5657 | switch (operation) { | 5657 | switch (operation) { |
| 5658 | case OperationType::Unmap: { | 5658 | case OperationType::Unmap: |
| 5659 | case OperationType::UnmapPhysical: { | ||
| 5660 | const bool separate_heap = operation == OperationType::UnmapPhysical; | ||
| 5661 | |||
| 5659 | // Ensure that any pages we track are closed on exit. | 5662 | // Ensure that any pages we track are closed on exit. |
| 5660 | KPageGroup pages_to_close(m_kernel, this->GetBlockInfoManager()); | 5663 | KPageGroup pages_to_close(m_kernel, this->GetBlockInfoManager()); |
| 5661 | SCOPE_EXIT({ pages_to_close.CloseAndReset(); }); | 5664 | SCOPE_EXIT({ pages_to_close.CloseAndReset(); }); |
| @@ -5664,7 +5667,7 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5664 | this->MakePageGroup(pages_to_close, virt_addr, num_pages); | 5667 | this->MakePageGroup(pages_to_close, virt_addr, num_pages); |
| 5665 | 5668 | ||
| 5666 | // Unmap. | 5669 | // Unmap. |
| 5667 | m_memory->UnmapRegion(*m_impl, virt_addr, num_pages * PageSize); | 5670 | m_memory->UnmapRegion(*m_impl, virt_addr, num_pages * PageSize, separate_heap); |
| 5668 | 5671 | ||
| 5669 | R_SUCCEED(); | 5672 | R_SUCCEED(); |
| 5670 | } | 5673 | } |
| @@ -5672,7 +5675,7 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5672 | ASSERT(virt_addr != 0); | 5675 | ASSERT(virt_addr != 0); |
| 5673 | ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize)); | 5676 | ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize)); |
| 5674 | m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr, | 5677 | m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr, |
| 5675 | ConvertToMemoryPermission(properties.perm)); | 5678 | ConvertToMemoryPermission(properties.perm), false); |
| 5676 | 5679 | ||
| 5677 | // Open references to pages, if we should. | 5680 | // Open references to pages, if we should. |
| 5678 | if (this->IsHeapPhysicalAddress(phys_addr)) { | 5681 | if (this->IsHeapPhysicalAddress(phys_addr)) { |
| @@ -5711,16 +5714,19 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5711 | 5714 | ||
| 5712 | switch (operation) { | 5715 | switch (operation) { |
| 5713 | case OperationType::MapGroup: | 5716 | case OperationType::MapGroup: |
| 5714 | case OperationType::MapFirstGroup: { | 5717 | case OperationType::MapFirstGroup: |
| 5718 | case OperationType::MapFirstGroupPhysical: { | ||
| 5719 | const bool separate_heap = operation == OperationType::MapFirstGroupPhysical; | ||
| 5720 | |||
| 5715 | // We want to maintain a new reference to every page in the group. | 5721 | // We want to maintain a new reference to every page in the group. |
| 5716 | KScopedPageGroup spg(page_group, operation != OperationType::MapFirstGroup); | 5722 | KScopedPageGroup spg(page_group, operation == OperationType::MapGroup); |
| 5717 | 5723 | ||
| 5718 | for (const auto& node : page_group) { | 5724 | for (const auto& node : page_group) { |
| 5719 | const size_t size{node.GetNumPages() * PageSize}; | 5725 | const size_t size{node.GetNumPages() * PageSize}; |
| 5720 | 5726 | ||
| 5721 | // Map the pages. | 5727 | // Map the pages. |
| 5722 | m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(), | 5728 | m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(), |
| 5723 | ConvertToMemoryPermission(properties.perm)); | 5729 | ConvertToMemoryPermission(properties.perm), separate_heap); |
| 5724 | 5730 | ||
| 5725 | virt_addr += size; | 5731 | virt_addr += size; |
| 5726 | } | 5732 | } |
diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h index 556d230b3..077cafc96 100644 --- a/src/core/hle/kernel/k_page_table_base.h +++ b/src/core/hle/kernel/k_page_table_base.h | |||
| @@ -104,6 +104,9 @@ protected: | |||
| 104 | ChangePermissionsAndRefresh = 5, | 104 | ChangePermissionsAndRefresh = 5, |
| 105 | ChangePermissionsAndRefreshAndFlush = 6, | 105 | ChangePermissionsAndRefreshAndFlush = 6, |
| 106 | Separate = 7, | 106 | Separate = 7, |
| 107 | |||
| 108 | MapFirstGroupPhysical = 65000, | ||
| 109 | UnmapPhysical = 65001, | ||
| 107 | }; | 110 | }; |
| 108 | 111 | ||
| 109 | static constexpr size_t MaxPhysicalMapAlignment = 1_GiB; | 112 | static constexpr size_t MaxPhysicalMapAlignment = 1_GiB; |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index d6869c228..068e71dff 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -1237,8 +1237,10 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) { | |||
| 1237 | auto& buffer = m_kernel.System().DeviceMemory().buffer; | 1237 | auto& buffer = m_kernel.System().DeviceMemory().buffer; |
| 1238 | const auto& code = code_set.CodeSegment(); | 1238 | const auto& code = code_set.CodeSegment(); |
| 1239 | const auto& patch = code_set.PatchSegment(); | 1239 | const auto& patch = code_set.PatchSegment(); |
| 1240 | buffer.Protect(GetInteger(base_addr + code.addr), code.size, true, true, true); | 1240 | buffer.Protect(GetInteger(base_addr + code.addr), code.size, |
| 1241 | buffer.Protect(GetInteger(base_addr + patch.addr), patch.size, true, true, true); | 1241 | Common::MemoryPermission::Read | Common::MemoryPermission::Execute); |
| 1242 | buffer.Protect(GetInteger(base_addr + patch.addr), patch.size, | ||
| 1243 | Common::MemoryPermission::Read | Common::MemoryPermission::Execute); | ||
| 1242 | ReprotectSegment(code_set.PatchSegment(), Svc::MemoryPermission::None); | 1244 | ReprotectSegment(code_set.PatchSegment(), Svc::MemoryPermission::None); |
| 1243 | } | 1245 | } |
| 1244 | #endif | 1246 | #endif |