diff options
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  void KPageTableBase::Finalize() {      auto HostUnmapCallback = [&](KProcessAddress addr, u64 size) {          if (Settings::IsFastmemEnabled()) { -            m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size); +            m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size, false);          }      }; @@ -5243,7 +5243,7 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) {                                  // Unmap.                                  R_ASSERT(this->Operate(updater.GetPageList(), cur_address,                                                         cur_pages, 0, false, unmap_properties, -                                                       OperationType::Unmap, true)); +                                                       OperationType::UnmapPhysical, true));                              }                              // Check if we're done. @@ -5326,7 +5326,7 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) {                              // Map the papges.                              R_TRY(this->Operate(updater.GetPageList(), cur_address, map_pages,                                                  cur_pg, map_properties, -                                                OperationType::MapFirstGroup, false)); +                                                OperationType::MapFirstGroupPhysical, false));                          }                      } @@ -5480,7 +5480,7 @@ Result KPageTableBase::UnmapPhysicalMemory(KProcessAddress address, size_t size)              // Unmap.              R_ASSERT(this->Operate(updater.GetPageList(), cur_address, cur_pages, 0, false, -                                   unmap_properties, OperationType::Unmap, false)); +                                   unmap_properties, OperationType::UnmapPhysical, false));          }          // Check if we're done. @@ -5655,7 +5655,10 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a      // or free them to the page list, and so it goes unused (along with page properties).      switch (operation) { -    case OperationType::Unmap: { +    case OperationType::Unmap: +    case OperationType::UnmapPhysical: { +        const bool separate_heap = operation == OperationType::UnmapPhysical; +          // Ensure that any pages we track are closed on exit.          KPageGroup pages_to_close(m_kernel, this->GetBlockInfoManager());          SCOPE_EXIT({ pages_to_close.CloseAndReset(); }); @@ -5664,7 +5667,7 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a          this->MakePageGroup(pages_to_close, virt_addr, num_pages);          // Unmap. -        m_memory->UnmapRegion(*m_impl, virt_addr, num_pages * PageSize); +        m_memory->UnmapRegion(*m_impl, virt_addr, num_pages * PageSize, separate_heap);          R_SUCCEED();      } @@ -5672,7 +5675,7 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a          ASSERT(virt_addr != 0);          ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));          m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr, -                                  ConvertToMemoryPermission(properties.perm)); +                                  ConvertToMemoryPermission(properties.perm), false);          // Open references to pages, if we should.          if (this->IsHeapPhysicalAddress(phys_addr)) { @@ -5711,16 +5714,19 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a      switch (operation) {      case OperationType::MapGroup: -    case OperationType::MapFirstGroup: { +    case OperationType::MapFirstGroup: +    case OperationType::MapFirstGroupPhysical: { +        const bool separate_heap = operation == OperationType::MapFirstGroupPhysical; +          // We want to maintain a new reference to every page in the group. -        KScopedPageGroup spg(page_group, operation != OperationType::MapFirstGroup); +        KScopedPageGroup spg(page_group, operation == OperationType::MapGroup);          for (const auto& node : page_group) {              const size_t size{node.GetNumPages() * PageSize};              // Map the pages.              m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(), -                                      ConvertToMemoryPermission(properties.perm)); +                                      ConvertToMemoryPermission(properties.perm), separate_heap);              virt_addr += size;          } 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:          ChangePermissionsAndRefresh = 5,          ChangePermissionsAndRefreshAndFlush = 6,          Separate = 7, + +        MapFirstGroupPhysical = 65000, +        UnmapPhysical = 65001,      };      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) {          auto& buffer = m_kernel.System().DeviceMemory().buffer;          const auto& code = code_set.CodeSegment();          const auto& patch = code_set.PatchSegment(); -        buffer.Protect(GetInteger(base_addr + code.addr), code.size, true, true, true); -        buffer.Protect(GetInteger(base_addr + patch.addr), patch.size, true, true, true); +        buffer.Protect(GetInteger(base_addr + code.addr), code.size, +                       Common::MemoryPermission::Read | Common::MemoryPermission::Execute); +        buffer.Protect(GetInteger(base_addr + patch.addr), patch.size, +                       Common::MemoryPermission::Read | Common::MemoryPermission::Execute);          ReprotectSegment(code_set.PatchSegment(), Svc::MemoryPermission::None);      }  #endif | 
