From 474db2d8dafebffc9a16dd3c9d1d21a63fdbeddd Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Fri, 14 Jul 2023 21:58:20 -0400
Subject: [PATCH] kernel: reduce page table region checking

---
 src/core/hle/kernel/k_page_table.h            | 41 ++++---------------
 src/core/hle/kernel/svc/svc_memory.cpp        | 25 +----------
 .../hle/kernel/svc/svc_physical_memory.cpp    |  8 ++--
 src/core/hle/kernel/svc/svc_process.cpp       |  4 +-
 .../hle/kernel/svc/svc_process_memory.cpp     | 20 +--------
 src/core/hle/kernel/svc/svc_thread.cpp        |  2 +-
 src/core/hle/service/ldr/ldr.cpp              |  6 +--
 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 022d15f355..b9e8c60421 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -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,
diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp
index bcf3d0d2b6..2cab741274 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
         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();
 }
 
diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp
index 56643c75c7..d3545f232b 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) {
         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);
diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp
index 4b438fe52e..caa8bee9af 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
     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);
diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp
index ee11e96390..07cd481755 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
     }
 
     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));
 }
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index d102e94a8c..92bcea72b3 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_
     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);
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 3d34917e86..055c0a2dbb 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -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;
                 }
 
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 1f87678e25..7b52f61a7f 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 {
 
 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_;
 }