diff options
| author | 2023-07-14 21:58:20 -0400 | |
|---|---|---|
| committer | 2023-07-14 22:33:10 -0400 | |
| commit | 474db2d8dafebffc9a16dd3c9d1d21a63fdbeddd (patch) | |
| tree | 288901313abc231a71faf3a95b24eabbca3a04d0 | |
| parent | k_process: PageTable -> GetPageTable (diff) | |
| download | yuzu-474db2d8dafebffc9a16dd3c9d1d21a63fdbeddd.tar.gz yuzu-474db2d8dafebffc9a16dd3c9d1d21a63fdbeddd.tar.xz yuzu-474db2d8dafebffc9a16dd3c9d1d21a63fdbeddd.zip | |
kernel: reduce page table region checking
| -rw-r--r-- | src/core/hle/kernel/k_page_table.h | 41 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_memory.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_physical_memory.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_process.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_process_memory.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_thread.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/ldr/ldr.cpp | 6 | ||||
| -rw-r--r-- | src/core/memory/cheat_engine.cpp | 4 |
8 files changed, 23 insertions, 87 deletions
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 022d15f35..b9e8c6042 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -388,39 +388,6 @@ public: | |||
| 388 | constexpr size_t GetHeapSize() const { | 388 | constexpr size_t GetHeapSize() const { |
| 389 | return m_current_heap_end - m_heap_region_start; | 389 | return m_current_heap_end - m_heap_region_start; |
| 390 | } | 390 | } |
| 391 | constexpr bool IsInsideAddressSpace(KProcessAddress address, size_t size) const { | ||
| 392 | return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1; | ||
| 393 | } | ||
| 394 | constexpr bool IsOutsideAliasRegion(KProcessAddress address, size_t size) const { | ||
| 395 | return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1; | ||
| 396 | } | ||
| 397 | constexpr bool IsOutsideStackRegion(KProcessAddress address, size_t size) const { | ||
| 398 | return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1; | ||
| 399 | } | ||
| 400 | constexpr bool IsInvalidRegion(KProcessAddress address, size_t size) const { | ||
| 401 | return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1; | ||
| 402 | } | ||
| 403 | constexpr bool IsInsideHeapRegion(KProcessAddress address, size_t size) const { | ||
| 404 | return address + size > m_heap_region_start && m_heap_region_end > address; | ||
| 405 | } | ||
| 406 | constexpr bool IsInsideAliasRegion(KProcessAddress address, size_t size) const { | ||
| 407 | return address + size > m_alias_region_start && m_alias_region_end > address; | ||
| 408 | } | ||
| 409 | constexpr bool IsOutsideASLRRegion(KProcessAddress address, size_t size) const { | ||
| 410 | if (IsInvalidRegion(address, size)) { | ||
| 411 | return true; | ||
| 412 | } | ||
| 413 | if (IsInsideHeapRegion(address, size)) { | ||
| 414 | return true; | ||
| 415 | } | ||
| 416 | if (IsInsideAliasRegion(address, size)) { | ||
| 417 | return true; | ||
| 418 | } | ||
| 419 | return {}; | ||
| 420 | } | ||
| 421 | constexpr bool IsInsideASLRRegion(KProcessAddress address, size_t size) const { | ||
| 422 | return !IsOutsideASLRRegion(address, size); | ||
| 423 | } | ||
| 424 | constexpr size_t GetNumGuardPages() const { | 391 | constexpr size_t GetNumGuardPages() const { |
| 425 | return IsKernel() ? 1 : 4; | 392 | return IsKernel() ? 1 : 4; |
| 426 | } | 393 | } |
| @@ -436,6 +403,14 @@ public: | |||
| 436 | return m_address_space_start <= addr && addr < addr + size && | 403 | return m_address_space_start <= addr && addr < addr + size && |
| 437 | addr + size - 1 <= m_address_space_end - 1; | 404 | addr + size - 1 <= m_address_space_end - 1; |
| 438 | } | 405 | } |
| 406 | constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const { | ||
| 407 | return this->Contains(addr, size) && m_alias_region_start <= addr && | ||
| 408 | addr + size - 1 <= m_alias_region_end - 1; | ||
| 409 | } | ||
| 410 | constexpr bool IsInHeapRegion(KProcessAddress addr, size_t size) const { | ||
| 411 | return this->Contains(addr, size) && m_heap_region_start <= addr && | ||
| 412 | addr + size - 1 <= m_heap_region_end - 1; | ||
| 413 | } | ||
| 439 | 414 | ||
| 440 | public: | 415 | public: |
| 441 | static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout, | 416 | static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout, |
diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp index bcf3d0d2b..2cab74127 100644 --- a/src/core/hle/kernel/svc/svc_memory.cpp +++ b/src/core/hle/kernel/svc/svc_memory.cpp | |||
| @@ -63,36 +63,13 @@ Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 s | |||
| 63 | R_THROW(ResultInvalidCurrentMemory); | 63 | R_THROW(ResultInvalidCurrentMemory); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | if (!manager.IsInsideAddressSpace(src_addr, size)) { | 66 | if (!manager.Contains(src_addr, size)) { |
| 67 | LOG_ERROR(Kernel_SVC, | 67 | LOG_ERROR(Kernel_SVC, |
| 68 | "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", | 68 | "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", |
| 69 | src_addr, size); | 69 | src_addr, size); |
| 70 | R_THROW(ResultInvalidCurrentMemory); | 70 | R_THROW(ResultInvalidCurrentMemory); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | if (manager.IsOutsideStackRegion(dst_addr, size)) { | ||
| 74 | LOG_ERROR(Kernel_SVC, | ||
| 75 | "Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}", | ||
| 76 | dst_addr, size); | ||
| 77 | R_THROW(ResultInvalidMemoryRegion); | ||
| 78 | } | ||
| 79 | |||
| 80 | if (manager.IsInsideHeapRegion(dst_addr, size)) { | ||
| 81 | LOG_ERROR(Kernel_SVC, | ||
| 82 | "Destination does not fit within the heap region, addr=0x{:016X}, " | ||
| 83 | "size=0x{:016X}", | ||
| 84 | dst_addr, size); | ||
| 85 | R_THROW(ResultInvalidMemoryRegion); | ||
| 86 | } | ||
| 87 | |||
| 88 | if (manager.IsInsideAliasRegion(dst_addr, size)) { | ||
| 89 | LOG_ERROR(Kernel_SVC, | ||
| 90 | "Destination does not fit within the map region, addr=0x{:016X}, " | ||
| 91 | "size=0x{:016X}", | ||
| 92 | dst_addr, size); | ||
| 93 | R_THROW(ResultInvalidMemoryRegion); | ||
| 94 | } | ||
| 95 | |||
| 96 | R_SUCCEED(); | 73 | R_SUCCEED(); |
| 97 | } | 74 | } |
| 98 | 75 | ||
diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp index 56643c75c..d3545f232 100644 --- a/src/core/hle/kernel/svc/svc_physical_memory.cpp +++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp | |||
| @@ -51,14 +51,14 @@ Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) { | |||
| 51 | R_THROW(ResultInvalidState); | 51 | R_THROW(ResultInvalidState); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | if (!page_table.IsInsideAddressSpace(addr, size)) { | 54 | if (!page_table.Contains(addr, size)) { |
| 55 | LOG_ERROR(Kernel_SVC, | 55 | LOG_ERROR(Kernel_SVC, |
| 56 | "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, | 56 | "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, |
| 57 | size); | 57 | size); |
| 58 | R_THROW(ResultInvalidMemoryRegion); | 58 | R_THROW(ResultInvalidMemoryRegion); |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | if (page_table.IsOutsideAliasRegion(addr, size)) { | 61 | if (!page_table.IsInAliasRegion(addr, size)) { |
| 62 | LOG_ERROR(Kernel_SVC, | 62 | LOG_ERROR(Kernel_SVC, |
| 63 | "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, | 63 | "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, |
| 64 | size); | 64 | size); |
| @@ -100,14 +100,14 @@ Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) { | |||
| 100 | R_THROW(ResultInvalidState); | 100 | R_THROW(ResultInvalidState); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | if (!page_table.IsInsideAddressSpace(addr, size)) { | 103 | if (!page_table.Contains(addr, size)) { |
| 104 | LOG_ERROR(Kernel_SVC, | 104 | LOG_ERROR(Kernel_SVC, |
| 105 | "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, | 105 | "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, |
| 106 | size); | 106 | size); |
| 107 | R_THROW(ResultInvalidMemoryRegion); | 107 | R_THROW(ResultInvalidMemoryRegion); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | if (page_table.IsOutsideAliasRegion(addr, size)) { | 110 | if (!page_table.IsInAliasRegion(addr, size)) { |
| 111 | LOG_ERROR(Kernel_SVC, | 111 | LOG_ERROR(Kernel_SVC, |
| 112 | "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, | 112 | "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, |
| 113 | size); | 113 | size); |
diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp index 4b438fe52..caa8bee9a 100644 --- a/src/core/hle/kernel/svc/svc_process.cpp +++ b/src/core/hle/kernel/svc/svc_process.cpp | |||
| @@ -66,8 +66,8 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_proc | |||
| 66 | auto& kernel = system.Kernel(); | 66 | auto& kernel = system.Kernel(); |
| 67 | const auto total_copy_size = out_process_ids_size * sizeof(u64); | 67 | const auto total_copy_size = out_process_ids_size * sizeof(u64); |
| 68 | 68 | ||
| 69 | if (out_process_ids_size > 0 && !GetCurrentProcess(kernel).GetPageTable().IsInsideAddressSpace( | 69 | if (out_process_ids_size > 0 && |
| 70 | out_process_ids, total_copy_size)) { | 70 | !GetCurrentProcess(kernel).GetPageTable().Contains(out_process_ids, total_copy_size)) { |
| 71 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", | 71 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", |
| 72 | out_process_ids, out_process_ids + total_copy_size); | 72 | out_process_ids, out_process_ids + total_copy_size); |
| 73 | R_THROW(ResultInvalidCurrentMemory); | 73 | R_THROW(ResultInvalidCurrentMemory); |
diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp index ee11e9639..07cd48175 100644 --- a/src/core/hle/kernel/svc/svc_process_memory.cpp +++ b/src/core/hle/kernel/svc/svc_process_memory.cpp | |||
| @@ -179,7 +179,7 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst | |||
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | auto& page_table = process->GetPageTable(); | 181 | auto& page_table = process->GetPageTable(); |
| 182 | if (!page_table.IsInsideAddressSpace(src_address, size)) { | 182 | if (!page_table.Contains(src_address, size)) { |
| 183 | LOG_ERROR(Kernel_SVC, | 183 | LOG_ERROR(Kernel_SVC, |
| 184 | "Source address range is not within the address space (src_address=0x{:016X}, " | 184 | "Source address range is not within the address space (src_address=0x{:016X}, " |
| 185 | "size=0x{:016X}).", | 185 | "size=0x{:016X}).", |
| @@ -187,14 +187,6 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst | |||
| 187 | R_THROW(ResultInvalidCurrentMemory); | 187 | R_THROW(ResultInvalidCurrentMemory); |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | if (!page_table.IsInsideASLRRegion(dst_address, size)) { | ||
| 191 | LOG_ERROR(Kernel_SVC, | ||
| 192 | "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " | ||
| 193 | "size=0x{:016X}).", | ||
| 194 | dst_address, size); | ||
| 195 | R_THROW(ResultInvalidMemoryRegion); | ||
| 196 | } | ||
| 197 | |||
| 198 | R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size)); | 190 | R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size)); |
| 199 | } | 191 | } |
| 200 | 192 | ||
| @@ -247,7 +239,7 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d | |||
| 247 | } | 239 | } |
| 248 | 240 | ||
| 249 | auto& page_table = process->GetPageTable(); | 241 | auto& page_table = process->GetPageTable(); |
| 250 | if (!page_table.IsInsideAddressSpace(src_address, size)) { | 242 | if (!page_table.Contains(src_address, size)) { |
| 251 | LOG_ERROR(Kernel_SVC, | 243 | LOG_ERROR(Kernel_SVC, |
| 252 | "Source address range is not within the address space (src_address=0x{:016X}, " | 244 | "Source address range is not within the address space (src_address=0x{:016X}, " |
| 253 | "size=0x{:016X}).", | 245 | "size=0x{:016X}).", |
| @@ -255,14 +247,6 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d | |||
| 255 | R_THROW(ResultInvalidCurrentMemory); | 247 | R_THROW(ResultInvalidCurrentMemory); |
| 256 | } | 248 | } |
| 257 | 249 | ||
| 258 | if (!page_table.IsInsideASLRRegion(dst_address, size)) { | ||
| 259 | LOG_ERROR(Kernel_SVC, | ||
| 260 | "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " | ||
| 261 | "size=0x{:016X}).", | ||
| 262 | dst_address, size); | ||
| 263 | R_THROW(ResultInvalidMemoryRegion); | ||
| 264 | } | ||
| 265 | |||
| 266 | R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size, | 250 | R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size, |
| 267 | KPageTable::ICacheInvalidationStrategy::InvalidateAll)); | 251 | KPageTable::ICacheInvalidationStrategy::InvalidateAll)); |
| 268 | } | 252 | } |
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index d102e94a8..92bcea72b 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp | |||
| @@ -236,7 +236,7 @@ Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_ | |||
| 236 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); | 236 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); |
| 237 | 237 | ||
| 238 | if (out_thread_ids_size > 0 && | 238 | if (out_thread_ids_size > 0 && |
| 239 | !current_process->GetPageTable().IsInsideAddressSpace(out_thread_ids, total_copy_size)) { | 239 | !current_process->GetPageTable().Contains(out_thread_ids, total_copy_size)) { |
| 240 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", | 240 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", |
| 241 | out_thread_ids, out_thread_ids + total_copy_size); | 241 | out_thread_ids, out_thread_ids + total_copy_size); |
| 242 | R_THROW(ResultInvalidCurrentMemory); | 242 | R_THROW(ResultInvalidCurrentMemory); |
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 3d34917e8..055c0a2db 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -318,15 +318,15 @@ public: | |||
| 318 | return false; | 318 | return false; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | if (!page_table.IsInsideAddressSpace(out_addr, size)) { | 321 | if (!page_table.Contains(out_addr, size)) { |
| 322 | return false; | 322 | return false; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | if (page_table.IsInsideHeapRegion(out_addr, size)) { | 325 | if (page_table.IsInHeapRegion(out_addr, size)) { |
| 326 | return false; | 326 | return false; |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | if (page_table.IsInsideAliasRegion(out_addr, size)) { | 329 | if (page_table.IsInAliasRegion(out_addr, size)) { |
| 330 | return false; | 330 | return false; |
| 331 | } | 331 | } |
| 332 | 332 | ||
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index 1f87678e2..7b52f61a7 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp | |||
| @@ -177,8 +177,8 @@ std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const { | |||
| 177 | 177 | ||
| 178 | CheatEngine::CheatEngine(System& system_, std::vector<CheatEntry> cheats_, | 178 | CheatEngine::CheatEngine(System& system_, std::vector<CheatEntry> cheats_, |
| 179 | const std::array<u8, 0x20>& build_id_) | 179 | const std::array<u8, 0x20>& build_id_) |
| 180 | : vm{std::make_unique<StandardVmCallbacks>(system_, metadata)}, cheats(std::move(cheats_)), | 180 | : vm{std::make_unique<StandardVmCallbacks>(system_, metadata)}, |
| 181 | core_timing{system_.CoreTiming()}, system{system_} { | 181 | cheats(std::move(cheats_)), core_timing{system_.CoreTiming()}, system{system_} { |
| 182 | metadata.main_nso_build_id = build_id_; | 182 | metadata.main_nso_build_id = build_id_; |
| 183 | } | 183 | } |
| 184 | 184 | ||