diff options
| author | 2023-11-17 21:43:15 +0200 | |
|---|---|---|
| committer | 2023-11-25 00:46:15 -0500 | |
| commit | 5938a9582a238d7679eb15f9812f8a85bfdb1cc3 (patch) | |
| tree | 935356a1cc03fea528e349d5027f2d885537272a /src/core/hle/kernel | |
| parent | host_memory: Switch to FreeRegionManager (diff) | |
| download | yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.tar.gz yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.tar.xz yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.zip | |
core: Respect memory permissions in Map
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/k_page_table_base.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 47dc8fd35..dc6524146 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp | |||
| @@ -88,6 +88,20 @@ Result FlushDataCache(AddressType addr, u64 size) { | |||
| 88 | R_SUCCEED(); | 88 | R_SUCCEED(); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | constexpr Common::MemoryPermission ConvertToMemoryPermission(KMemoryPermission perm) { | ||
| 92 | Common::MemoryPermission perms{}; | ||
| 93 | if (True(perm & KMemoryPermission::UserRead)) { | ||
| 94 | perms |= Common::MemoryPermission::Read; | ||
| 95 | } | ||
| 96 | if (True(perm & KMemoryPermission::UserWrite)) { | ||
| 97 | perms |= Common::MemoryPermission::Write; | ||
| 98 | } | ||
| 99 | if (True(perm & KMemoryPermission::UserExecute)) { | ||
| 100 | perms |= Common::MemoryPermission::Execute; | ||
| 101 | } | ||
| 102 | return perms; | ||
| 103 | } | ||
| 104 | |||
| 91 | } // namespace | 105 | } // namespace |
| 92 | 106 | ||
| 93 | void KPageTableBase::MemoryRange::Open() { | 107 | void KPageTableBase::MemoryRange::Open() { |
| @@ -5643,7 +5657,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5643 | case OperationType::Map: { | 5657 | case OperationType::Map: { |
| 5644 | ASSERT(virt_addr != 0); | 5658 | ASSERT(virt_addr != 0); |
| 5645 | ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize)); | 5659 | ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize)); |
| 5646 | m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr); | 5660 | m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr, |
| 5661 | ConvertToMemoryPermission(properties.perm)); | ||
| 5647 | 5662 | ||
| 5648 | // Open references to pages, if we should. | 5663 | // Open references to pages, if we should. |
| 5649 | if (this->IsHeapPhysicalAddress(phys_addr)) { | 5664 | if (this->IsHeapPhysicalAddress(phys_addr)) { |
| @@ -5658,8 +5673,18 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5658 | } | 5673 | } |
| 5659 | case OperationType::ChangePermissions: | 5674 | case OperationType::ChangePermissions: |
| 5660 | case OperationType::ChangePermissionsAndRefresh: | 5675 | case OperationType::ChangePermissionsAndRefresh: |
| 5661 | case OperationType::ChangePermissionsAndRefreshAndFlush: | 5676 | case OperationType::ChangePermissionsAndRefreshAndFlush: { |
| 5677 | const bool read = True(properties.perm & Kernel::KMemoryPermission::UserRead); | ||
| 5678 | const bool write = True(properties.perm & Kernel::KMemoryPermission::UserWrite); | ||
| 5679 | // todo: this doesn't really belong here and should go into m_memory to handle rasterizer | ||
| 5680 | // access todo: ignore exec on non-direct-mapped case | ||
| 5681 | const bool exec = True(properties.perm & Kernel::KMemoryPermission::UserExecute); | ||
| 5682 | if (Settings::IsFastmemEnabled()) { | ||
| 5683 | m_system.DeviceMemory().buffer.Protect(GetInteger(virt_addr), num_pages * PageSize, | ||
| 5684 | read, write, exec); | ||
| 5685 | } | ||
| 5662 | R_SUCCEED(); | 5686 | R_SUCCEED(); |
| 5687 | } | ||
| 5663 | default: | 5688 | default: |
| 5664 | UNREACHABLE(); | 5689 | UNREACHABLE(); |
| 5665 | } | 5690 | } |
| @@ -5687,7 +5712,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5687 | const size_t size{node.GetNumPages() * PageSize}; | 5712 | const size_t size{node.GetNumPages() * PageSize}; |
| 5688 | 5713 | ||
| 5689 | // Map the pages. | 5714 | // Map the pages. |
| 5690 | m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress()); | 5715 | m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(), |
| 5716 | ConvertToMemoryPermission(properties.perm)); | ||
| 5691 | 5717 | ||
| 5692 | virt_addr += size; | 5718 | virt_addr += size; |
| 5693 | } | 5719 | } |