forked from suyu/suyu
kernel: reduce page table region checking
This commit is contained in:
parent
a85ce8ea56
commit
474db2d8da
8 changed files with 23 additions and 87 deletions
|
@ -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_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue