kernel: reduce page table region checking

This commit is contained in:
Liam 2023-07-14 21:58:20 -04:00
parent a85ce8ea56
commit 474db2d8da
8 changed files with 23 additions and 87 deletions

View File

@ -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,

View File

@ -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();
} }

View File

@ -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);

View File

@ -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);

View File

@ -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));
} }

View File

@ -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);

View File

@ -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;
} }

View File

@ -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_;
} }