kernel: reduce page table region checking
This commit is contained in:
		| @@ -388,39 +388,6 @@ public: | ||||
|     constexpr size_t GetHeapSize() const { | ||||
|         return m_current_heap_end - m_heap_region_start; | ||||
|     } | ||||
|     constexpr bool IsInsideAddressSpace(KProcessAddress address, size_t size) const { | ||||
|         return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1; | ||||
|     } | ||||
|     constexpr bool IsOutsideAliasRegion(KProcessAddress address, size_t size) const { | ||||
|         return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1; | ||||
|     } | ||||
|     constexpr bool IsOutsideStackRegion(KProcessAddress address, size_t size) const { | ||||
|         return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1; | ||||
|     } | ||||
|     constexpr bool IsInvalidRegion(KProcessAddress address, size_t size) const { | ||||
|         return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1; | ||||
|     } | ||||
|     constexpr bool IsInsideHeapRegion(KProcessAddress address, size_t size) const { | ||||
|         return address + size > m_heap_region_start && m_heap_region_end > address; | ||||
|     } | ||||
|     constexpr bool IsInsideAliasRegion(KProcessAddress address, size_t size) const { | ||||
|         return address + size > m_alias_region_start && m_alias_region_end > address; | ||||
|     } | ||||
|     constexpr bool IsOutsideASLRRegion(KProcessAddress address, size_t size) const { | ||||
|         if (IsInvalidRegion(address, size)) { | ||||
|             return true; | ||||
|         } | ||||
|         if (IsInsideHeapRegion(address, size)) { | ||||
|             return true; | ||||
|         } | ||||
|         if (IsInsideAliasRegion(address, size)) { | ||||
|             return true; | ||||
|         } | ||||
|         return {}; | ||||
|     } | ||||
|     constexpr bool IsInsideASLRRegion(KProcessAddress address, size_t size) const { | ||||
|         return !IsOutsideASLRRegion(address, size); | ||||
|     } | ||||
|     constexpr size_t GetNumGuardPages() const { | ||||
|         return IsKernel() ? 1 : 4; | ||||
|     } | ||||
| @@ -436,6 +403,14 @@ public: | ||||
|         return m_address_space_start <= addr && addr < addr + size && | ||||
|                addr + size - 1 <= m_address_space_end - 1; | ||||
|     } | ||||
|     constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const { | ||||
|         return this->Contains(addr, size) && m_alias_region_start <= addr && | ||||
|                addr + size - 1 <= m_alias_region_end - 1; | ||||
|     } | ||||
|     constexpr bool IsInHeapRegion(KProcessAddress addr, size_t size) const { | ||||
|         return this->Contains(addr, size) && m_heap_region_start <= addr && | ||||
|                addr + size - 1 <= m_heap_region_end - 1; | ||||
|     } | ||||
|  | ||||
| public: | ||||
|     static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout, | ||||
|   | ||||
| @@ -63,36 +63,13 @@ Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 s | ||||
|         R_THROW(ResultInvalidCurrentMemory); | ||||
|     } | ||||
|  | ||||
|     if (!manager.IsInsideAddressSpace(src_addr, size)) { | ||||
|     if (!manager.Contains(src_addr, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", | ||||
|                   src_addr, size); | ||||
|         R_THROW(ResultInvalidCurrentMemory); | ||||
|     } | ||||
|  | ||||
|     if (manager.IsOutsideStackRegion(dst_addr, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}", | ||||
|                   dst_addr, size); | ||||
|         R_THROW(ResultInvalidMemoryRegion); | ||||
|     } | ||||
|  | ||||
|     if (manager.IsInsideHeapRegion(dst_addr, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Destination does not fit within the heap region, addr=0x{:016X}, " | ||||
|                   "size=0x{:016X}", | ||||
|                   dst_addr, size); | ||||
|         R_THROW(ResultInvalidMemoryRegion); | ||||
|     } | ||||
|  | ||||
|     if (manager.IsInsideAliasRegion(dst_addr, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Destination does not fit within the map region, addr=0x{:016X}, " | ||||
|                   "size=0x{:016X}", | ||||
|                   dst_addr, size); | ||||
|         R_THROW(ResultInvalidMemoryRegion); | ||||
|     } | ||||
|  | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -51,14 +51,14 @@ Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) { | ||||
|         R_THROW(ResultInvalidState); | ||||
|     } | ||||
|  | ||||
|     if (!page_table.IsInsideAddressSpace(addr, size)) { | ||||
|     if (!page_table.Contains(addr, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, | ||||
|                   size); | ||||
|         R_THROW(ResultInvalidMemoryRegion); | ||||
|     } | ||||
|  | ||||
|     if (page_table.IsOutsideAliasRegion(addr, size)) { | ||||
|     if (!page_table.IsInAliasRegion(addr, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, | ||||
|                   size); | ||||
| @@ -100,14 +100,14 @@ Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) { | ||||
|         R_THROW(ResultInvalidState); | ||||
|     } | ||||
|  | ||||
|     if (!page_table.IsInsideAddressSpace(addr, size)) { | ||||
|     if (!page_table.Contains(addr, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, | ||||
|                   size); | ||||
|         R_THROW(ResultInvalidMemoryRegion); | ||||
|     } | ||||
|  | ||||
|     if (page_table.IsOutsideAliasRegion(addr, size)) { | ||||
|     if (!page_table.IsInAliasRegion(addr, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, | ||||
|                   size); | ||||
|   | ||||
| @@ -66,8 +66,8 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_proc | ||||
|     auto& kernel = system.Kernel(); | ||||
|     const auto total_copy_size = out_process_ids_size * sizeof(u64); | ||||
|  | ||||
|     if (out_process_ids_size > 0 && !GetCurrentProcess(kernel).GetPageTable().IsInsideAddressSpace( | ||||
|                                         out_process_ids, total_copy_size)) { | ||||
|     if (out_process_ids_size > 0 && | ||||
|         !GetCurrentProcess(kernel).GetPageTable().Contains(out_process_ids, total_copy_size)) { | ||||
|         LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", | ||||
|                   out_process_ids, out_process_ids + total_copy_size); | ||||
|         R_THROW(ResultInvalidCurrentMemory); | ||||
|   | ||||
| @@ -179,7 +179,7 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst | ||||
|     } | ||||
|  | ||||
|     auto& page_table = process->GetPageTable(); | ||||
|     if (!page_table.IsInsideAddressSpace(src_address, size)) { | ||||
|     if (!page_table.Contains(src_address, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Source address range is not within the address space (src_address=0x{:016X}, " | ||||
|                   "size=0x{:016X}).", | ||||
| @@ -187,14 +187,6 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst | ||||
|         R_THROW(ResultInvalidCurrentMemory); | ||||
|     } | ||||
|  | ||||
|     if (!page_table.IsInsideASLRRegion(dst_address, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " | ||||
|                   "size=0x{:016X}).", | ||||
|                   dst_address, size); | ||||
|         R_THROW(ResultInvalidMemoryRegion); | ||||
|     } | ||||
|  | ||||
|     R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size)); | ||||
| } | ||||
|  | ||||
| @@ -247,7 +239,7 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d | ||||
|     } | ||||
|  | ||||
|     auto& page_table = process->GetPageTable(); | ||||
|     if (!page_table.IsInsideAddressSpace(src_address, size)) { | ||||
|     if (!page_table.Contains(src_address, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Source address range is not within the address space (src_address=0x{:016X}, " | ||||
|                   "size=0x{:016X}).", | ||||
| @@ -255,14 +247,6 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d | ||||
|         R_THROW(ResultInvalidCurrentMemory); | ||||
|     } | ||||
|  | ||||
|     if (!page_table.IsInsideASLRRegion(dst_address, size)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " | ||||
|                   "size=0x{:016X}).", | ||||
|                   dst_address, size); | ||||
|         R_THROW(ResultInvalidMemoryRegion); | ||||
|     } | ||||
|  | ||||
|     R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size, | ||||
|                                         KPageTable::ICacheInvalidationStrategy::InvalidateAll)); | ||||
| } | ||||
|   | ||||
| @@ -236,7 +236,7 @@ Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_ | ||||
|     const auto total_copy_size = out_thread_ids_size * sizeof(u64); | ||||
|  | ||||
|     if (out_thread_ids_size > 0 && | ||||
|         !current_process->GetPageTable().IsInsideAddressSpace(out_thread_ids, total_copy_size)) { | ||||
|         !current_process->GetPageTable().Contains(out_thread_ids, total_copy_size)) { | ||||
|         LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", | ||||
|                   out_thread_ids, out_thread_ids + total_copy_size); | ||||
|         R_THROW(ResultInvalidCurrentMemory); | ||||
|   | ||||
| @@ -318,15 +318,15 @@ public: | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 if (!page_table.IsInsideAddressSpace(out_addr, size)) { | ||||
|                 if (!page_table.Contains(out_addr, size)) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 if (page_table.IsInsideHeapRegion(out_addr, size)) { | ||||
|                 if (page_table.IsInHeapRegion(out_addr, size)) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 if (page_table.IsInsideAliasRegion(out_addr, size)) { | ||||
|                 if (page_table.IsInAliasRegion(out_addr, size)) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|   | ||||
| @@ -177,8 +177,8 @@ std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const { | ||||
|  | ||||
| CheatEngine::CheatEngine(System& system_, std::vector<CheatEntry> cheats_, | ||||
|                          const std::array<u8, 0x20>& build_id_) | ||||
|     : vm{std::make_unique<StandardVmCallbacks>(system_, metadata)}, cheats(std::move(cheats_)), | ||||
|       core_timing{system_.CoreTiming()}, system{system_} { | ||||
|     : vm{std::make_unique<StandardVmCallbacks>(system_, metadata)}, | ||||
|       cheats(std::move(cheats_)), core_timing{system_.CoreTiming()}, system{system_} { | ||||
|     metadata.main_nso_build_id = build_id_; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Liam
					Liam