diff options
| author | 2018-12-10 10:09:50 -0500 | |
|---|---|---|
| committer | 2018-12-10 10:09:50 -0500 | |
| commit | 74242a8fb459c656ba26308bc5d08da3fd5db1a1 (patch) | |
| tree | 492582574dc559b463aa51581017c4cf1d8cef0d /src/core/hle/kernel | |
| parent | Merge pull request #1862 from marcosvitali/tlds (diff) | |
| parent | memory: Convert ASSERT into a DEBUG_ASSERT within GetPointerFromVMA() (diff) | |
| download | yuzu-74242a8fb459c656ba26308bc5d08da3fd5db1a1.tar.gz yuzu-74242a8fb459c656ba26308bc5d08da3fd5db1a1.tar.xz yuzu-74242a8fb459c656ba26308bc5d08da3fd5db1a1.zip | |
Merge pull request #1876 from lioncash/vma
vm_manager: Make vma_map private
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.h | 26 |
4 files changed, 36 insertions, 22 deletions
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 0494581f5..d1ca60125 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -39,15 +39,15 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, SharedPtr<Proce | |||
| 39 | shared_memory->backing_block.get()); | 39 | shared_memory->backing_block.get()); |
| 40 | } | 40 | } |
| 41 | } else { | 41 | } else { |
| 42 | auto& vm_manager = shared_memory->owner_process->VMManager(); | 42 | const auto& vm_manager = shared_memory->owner_process->VMManager(); |
| 43 | 43 | ||
| 44 | // The memory is already available and mapped in the owner process. | 44 | // The memory is already available and mapped in the owner process. |
| 45 | auto vma = vm_manager.FindVMA(address); | 45 | const auto vma = vm_manager.FindVMA(address); |
| 46 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); | 46 | ASSERT_MSG(vm_manager.IsValidHandle(vma), "Invalid memory address"); |
| 47 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); | 47 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); |
| 48 | 48 | ||
| 49 | // The returned VMA might be a bigger one encompassing the desired address. | 49 | // The returned VMA might be a bigger one encompassing the desired address. |
| 50 | auto vma_offset = address - vma->first; | 50 | const auto vma_offset = address - vma->first; |
| 51 | ASSERT_MSG(vma_offset + size <= vma->second.size, | 51 | ASSERT_MSG(vma_offset + size <= vma->second.size, |
| 52 | "Shared memory exceeds bounds of mapped block"); | 52 | "Shared memory exceeds bounds of mapped block"); |
| 53 | 53 | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 84df2040e..f43c7201c 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -239,7 +239,7 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { | |||
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); | 241 | const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); |
| 242 | if (iter == vm_manager.vma_map.end()) { | 242 | if (!vm_manager.IsValidHandle(iter)) { |
| 243 | LOG_ERROR(Kernel_SVC, "Unable to find VMA for address=0x{:016X}", addr); | 243 | LOG_ERROR(Kernel_SVC, "Unable to find VMA for address=0x{:016X}", addr); |
| 244 | return ERR_INVALID_ADDRESS_STATE; | 244 | return ERR_INVALID_ADDRESS_STATE; |
| 245 | } | 245 | } |
| @@ -1077,19 +1077,23 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i | |||
| 1077 | process_handle); | 1077 | process_handle); |
| 1078 | return ERR_INVALID_HANDLE; | 1078 | return ERR_INVALID_HANDLE; |
| 1079 | } | 1079 | } |
| 1080 | auto vma = process->VMManager().FindVMA(addr); | 1080 | |
| 1081 | const auto& vm_manager = process->VMManager(); | ||
| 1082 | const auto vma = vm_manager.FindVMA(addr); | ||
| 1083 | |||
| 1081 | memory_info->attributes = 0; | 1084 | memory_info->attributes = 0; |
| 1082 | if (vma == process->VMManager().vma_map.end()) { | 1085 | if (vm_manager.IsValidHandle(vma)) { |
| 1083 | memory_info->base_address = 0; | ||
| 1084 | memory_info->permission = static_cast<u32>(VMAPermission::None); | ||
| 1085 | memory_info->size = 0; | ||
| 1086 | memory_info->type = static_cast<u32>(MemoryState::Unmapped); | ||
| 1087 | } else { | ||
| 1088 | memory_info->base_address = vma->second.base; | 1086 | memory_info->base_address = vma->second.base; |
| 1089 | memory_info->permission = static_cast<u32>(vma->second.permissions); | 1087 | memory_info->permission = static_cast<u32>(vma->second.permissions); |
| 1090 | memory_info->size = vma->second.size; | 1088 | memory_info->size = vma->second.size; |
| 1091 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); | 1089 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); |
| 1090 | } else { | ||
| 1091 | memory_info->base_address = 0; | ||
| 1092 | memory_info->permission = static_cast<u32>(VMAPermission::None); | ||
| 1093 | memory_info->size = 0; | ||
| 1094 | memory_info->type = static_cast<u32>(MemoryState::Unmapped); | ||
| 1092 | } | 1095 | } |
| 1096 | |||
| 1093 | return RESULT_SUCCESS; | 1097 | return RESULT_SUCCESS; |
| 1094 | } | 1098 | } |
| 1095 | 1099 | ||
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 100f8f6bf..6187993ce 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -87,6 +87,10 @@ VMManager::VMAHandle VMManager::FindVMA(VAddr target) const { | |||
| 87 | } | 87 | } |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | bool VMManager::IsValidHandle(VMAHandle handle) const { | ||
| 91 | return handle != vma_map.cend(); | ||
| 92 | } | ||
| 93 | |||
| 90 | ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, | 94 | ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, |
| 91 | std::shared_ptr<std::vector<u8>> block, | 95 | std::shared_ptr<std::vector<u8>> block, |
| 92 | std::size_t offset, u64 size, | 96 | std::size_t offset, u64 size, |
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index d522404fe..a12419d1e 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h | |||
| @@ -113,16 +113,10 @@ struct VirtualMemoryArea { | |||
| 113 | * - http://duartes.org/gustavo/blog/post/page-cache-the-affair-between-memory-and-files/ | 113 | * - http://duartes.org/gustavo/blog/post/page-cache-the-affair-between-memory-and-files/ |
| 114 | */ | 114 | */ |
| 115 | class VMManager final { | 115 | class VMManager final { |
| 116 | using VMAMap = std::map<VAddr, VirtualMemoryArea>; | ||
| 117 | |||
| 116 | public: | 118 | public: |
| 117 | /** | 119 | using VMAHandle = VMAMap::const_iterator; |
| 118 | * A map covering the entirety of the managed address space, keyed by the `base` field of each | ||
| 119 | * VMA. It must always be modified by splitting or merging VMAs, so that the invariant | ||
| 120 | * `elem.base + elem.size == next.base` is preserved, and mergeable regions must always be | ||
| 121 | * merged when possible so that no two similar and adjacent regions exist that have not been | ||
| 122 | * merged. | ||
| 123 | */ | ||
| 124 | std::map<VAddr, VirtualMemoryArea> vma_map; | ||
| 125 | using VMAHandle = decltype(vma_map)::const_iterator; | ||
| 126 | 120 | ||
| 127 | VMManager(); | 121 | VMManager(); |
| 128 | ~VMManager(); | 122 | ~VMManager(); |
| @@ -133,6 +127,9 @@ public: | |||
| 133 | /// Finds the VMA in which the given address is included in, or `vma_map.end()`. | 127 | /// Finds the VMA in which the given address is included in, or `vma_map.end()`. |
| 134 | VMAHandle FindVMA(VAddr target) const; | 128 | VMAHandle FindVMA(VAddr target) const; |
| 135 | 129 | ||
| 130 | /// Indicates whether or not the given handle is within the VMA map. | ||
| 131 | bool IsValidHandle(VMAHandle handle) const; | ||
| 132 | |||
| 136 | // TODO(yuriks): Should these functions actually return the handle? | 133 | // TODO(yuriks): Should these functions actually return the handle? |
| 137 | 134 | ||
| 138 | /** | 135 | /** |
| @@ -281,7 +278,7 @@ public: | |||
| 281 | Memory::PageTable page_table; | 278 | Memory::PageTable page_table; |
| 282 | 279 | ||
| 283 | private: | 280 | private: |
| 284 | using VMAIter = decltype(vma_map)::iterator; | 281 | using VMAIter = VMAMap::iterator; |
| 285 | 282 | ||
| 286 | /// Converts a VMAHandle to a mutable VMAIter. | 283 | /// Converts a VMAHandle to a mutable VMAIter. |
| 287 | VMAIter StripIterConstness(const VMAHandle& iter); | 284 | VMAIter StripIterConstness(const VMAHandle& iter); |
| @@ -328,6 +325,15 @@ private: | |||
| 328 | /// Clears out the page table | 325 | /// Clears out the page table |
| 329 | void ClearPageTable(); | 326 | void ClearPageTable(); |
| 330 | 327 | ||
| 328 | /** | ||
| 329 | * A map covering the entirety of the managed address space, keyed by the `base` field of each | ||
| 330 | * VMA. It must always be modified by splitting or merging VMAs, so that the invariant | ||
| 331 | * `elem.base + elem.size == next.base` is preserved, and mergeable regions must always be | ||
| 332 | * merged when possible so that no two similar and adjacent regions exist that have not been | ||
| 333 | * merged. | ||
| 334 | */ | ||
| 335 | VMAMap vma_map; | ||
| 336 | |||
| 331 | u32 address_space_width = 0; | 337 | u32 address_space_width = 0; |
| 332 | VAddr address_space_base = 0; | 338 | VAddr address_space_base = 0; |
| 333 | VAddr address_space_end = 0; | 339 | VAddr address_space_end = 0; |