From e252c4a729a6e57c275dc1772399476de297d0c9 Mon Sep 17 00:00:00 2001 From: "Jared M. White" Date: Wed, 3 Jul 2024 06:29:15 -0500 Subject: [PATCH] Reorganize so that we're calling any memory protectives from the arena --- Source/Core/Common/MemArena.h | 5 +++-- Source/Core/Common/MemArenaWin.cpp | 4 ++-- Source/Core/Core/HW/Memmap.cpp | 16 ++++++++++------ Source/Core/Core/HW/Memmap.h | 4 +++- Source/Core/Core/MemTools.cpp | 14 +++++++------- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Source/Core/Common/MemArena.h b/Source/Core/Common/MemArena.h index 4f9ee59e33..baaba5c556 100644 --- a/Source/Core/Common/MemArena.h +++ b/Source/Core/Common/MemArena.h @@ -113,12 +113,13 @@ public: void UnmapFromMemoryRegion(void* view, size_t size); /// - /// Write protect a section from the memory region previously mapped by CreateView. + /// Virtual protect a section from the memory region previously mapped by CreateView. /// /// @param data Pointer to data to protect. /// @param size Size of the protection. + /// @param flag What new permission to protect with. /// - bool WriteProtectMemoryRegion(u8* data, size_t size); + bool VirtualProtectMemoryRegion(u8* data, size_t size, u64 flag); private: #ifdef _WIN32 diff --git a/Source/Core/Common/MemArenaWin.cpp b/Source/Core/Common/MemArenaWin.cpp index 0958a6b333..7eb10d9877 100644 --- a/Source/Core/Common/MemArenaWin.cpp +++ b/Source/Core/Common/MemArenaWin.cpp @@ -215,11 +215,11 @@ void MemArena::ReleaseMemoryRegion() } } -bool MemArena::WriteProtectMemoryRegion(u8* data, size_t size) +bool MemArena::VirtualProtectMemoryRegion(u8* data, size_t size, u64 flag) { DWORD lpflOldProtect = 0; return static_cast(m_memory_functions.m_address_VirtualProtect)( - data, size, PAGE_READONLY, &lpflOldProtect); + data, size, flag, &lpflOldProtect); } WindowsMemoryRegion* MemArena::EnsureSplitRegionForMapping(void* start_address, size_t size) diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index 1d88c3db64..ffd025ad50 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -54,7 +54,12 @@ std::optional MemoryManager::GetDirtyPageIndexFromAddress(u64 address) return (address & ~page_mask) >> 12; } -void MemoryManager::WriteProtectMemory() +bool MemoryManager::VirtualProtectMemory(u8* data, size_t size, u64 flag) +{ + return m_arena.VirtualProtectMemoryRegion(data, size, flag); +} + +void MemoryManager::WriteProtectPhysicalMemoryRegions() { for (const PhysicalMemoryRegion& region : m_physical_regions) { @@ -63,12 +68,11 @@ void MemoryManager::WriteProtectMemory() size_t page_size = Common::PageSize(); for (size_t i = 0; i < region.size; i += page_size) { - bool change_protection = - m_arena.WriteProtectMemoryRegion((*region.out_pointer) + i, page_size); + bool change_protection = VirtualProtectMemory((*region.out_pointer) + i, page_size, PAGE_READONLY); if (!change_protection) { PanicAlertFmt( - "Memory::Init(): Failed to write protect for this block of memory at 0x{:08X}.", + "Memory::WriteProtectPhysicalMemoryRegions(): Failed to write protect for this block of memory at 0x{:08X}.", reinterpret_cast(*region.out_pointer)); } std::optional index = @@ -105,7 +109,7 @@ void MemoryManager::InitMMIO(bool is_wii) void MemoryManager::InitDirtyPages() { - WriteProtectMemory(); + WriteProtectPhysicalMemoryRegions(); } void MemoryManager::Init() @@ -675,7 +679,7 @@ void MemoryManager::SetPageDirtyBit(uintptr_t address, size_t size, bool dirty) void MemoryManager::ResetDirtyPages() { - WriteProtectMemory(); + WriteProtectPhysicalMemoryRegions(); } } // namespace Memory diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index 0a397e81b5..dbcdd5bf68 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -135,6 +135,7 @@ public: bool IsPageDirty(uintptr_t address); void SetPageDirtyBit(uintptr_t address, size_t size, bool dirty); void ResetDirtyPages(); + bool VirtualProtectMemory(u8* data, size_t size, u64 flag); std::map& GetDirtyPages() { return m_dirty_pages; } @@ -265,7 +266,8 @@ private: std::map m_dirty_pages; std::optional GetDirtyPageIndexFromAddress(u64 address); - void WriteProtectMemory(); + void WriteProtectPhysicalMemoryRegions(); + void InitMMIO(bool is_wii); }; } // namespace Memory diff --git a/Source/Core/Core/MemTools.cpp b/Source/Core/Core/MemTools.cpp index 1316a76c70..1539a0d685 100644 --- a/Source/Core/Core/MemTools.cpp +++ b/Source/Core/Core/MemTools.cpp @@ -62,21 +62,21 @@ static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) // virtual address of the inaccessible data uintptr_t fault_address = (uintptr_t)pPtrs->ExceptionRecord->ExceptionInformation[1]; SContext* ctx = pPtrs->ContextRecord; - if (Core::System::GetInstance().GetJitInterface().HandleFault(fault_address, ctx)) + Core::System& system = Core::System::GetInstance(); + Memory::MemoryManager& memory = system.GetMemory(); + if (system.GetJitInterface().HandleFault(fault_address, ctx)) { return EXCEPTION_CONTINUE_EXECUTION; } - else if (!Core::System::GetInstance().GetMemory().IsPageDirty(fault_address)) + else if (!memory.IsPageDirty(fault_address)) { - Core::System::GetInstance().GetMemory().SetPageDirtyBit(fault_address, 1, true); + memory.SetPageDirtyBit(fault_address, 1, true); size_t page_size = Common::PageSize(); size_t page_mask = page_size - 1; u64 page_index = fault_address & page_mask; - DWORD lpflOldProtect = 0; - bool change_protection = - VirtualProtect(reinterpret_cast(fault_address), page_size - page_index, - PAGE_READWRITE, &lpflOldProtect); + bool change_protection = memory.VirtualProtectMemory(reinterpret_cast(fault_address), + page_size - page_index, PAGE_READWRITE); if (!change_protection) { return EXCEPTION_CONTINUE_SEARCH;