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