CPU/CodeCache: Assert that handlers execute on core thread

And fastmem exceptions come from within the code buffer.
pull/3782/head
Stenzek 1 month ago
parent 7304bfe256
commit 83a03fe955
No known key found for this signature in database

@ -85,6 +85,8 @@ static void SetCodeLUT(u32 pc, const void* function);
static void InvalidateBlock(Block* block, BlockState new_state); static void InvalidateBlock(Block* block, BlockState new_state);
static void ClearBlocks(); static void ClearBlocks();
static bool IsInCodeBuffer(const void* pc);
static Block* LookupBlock(u32 pc); static Block* LookupBlock(u32 pc);
static Block* CreateBlock(u32 pc, const BlockInstructionList& instructions, const BlockMetadata& metadata); static Block* CreateBlock(u32 pc, const BlockInstructionList& instructions, const BlockMetadata& metadata);
static bool HasBlockLUT(u32 pc); static bool HasBlockLUT(u32 pc);
@ -188,6 +190,15 @@ bool CPU::CodeCache::IsUsingFastmem()
return (g_settings.cpu_fastmem_mode != CPUFastmemMode::Disabled); return (g_settings.cpu_fastmem_mode != CPUFastmemMode::Disabled);
} }
bool CPU::CodeCache::IsInCodeBuffer(const void* pc)
{
#ifdef USE_CODE_BUFFER_SECTION
return (pc >= s_code_buffer_storage && pc < (s_code_buffer_storage + RECOMPILER_CODE_CACHE_SIZE));
#else
return (pc >= s_locals.code_buffer_ptr && pc < (s_locals.code_buffer_ptr + RECOMPILER_CODE_CACHE_SIZE));
#endif
}
bool CPU::CodeCache::ProcessStartup(Error* error) bool CPU::CodeCache::ProcessStartup(Error* error)
{ {
#ifdef USE_CODE_BUFFER_SECTION #ifdef USE_CODE_BUFFER_SECTION
@ -764,8 +775,10 @@ PageFaultHandler::HandlerResult PageFaultHandler::HandlePageFault(void* exceptio
if (g_bus.ram && static_cast<const u8*>(fault_address) >= g_bus.ram && if (g_bus.ram && static_cast<const u8*>(fault_address) >= g_bus.ram &&
static_cast<const u8*>(fault_address) < (g_bus.ram + Bus::RAM_8MB_SIZE)) static_cast<const u8*>(fault_address) < (g_bus.ram + Bus::RAM_8MB_SIZE))
{ {
// Writing to protected RAM. // Writing to protected RAM should only occur on the core thread.
DebugAssert(is_write); // Writes can come from anywhere here (e.g. DMA).
Assert(is_write && Host::IsOnCoreThread());
const u32 guest_address = static_cast<u32>(static_cast<const u8*>(fault_address) - g_bus.ram); const u32 guest_address = static_cast<u32>(static_cast<const u8*>(fault_address) - g_bus.ram);
const u32 page_index = Bus::GetRAMCodePageIndex(guest_address); const u32 page_index = Bus::GetRAMCodePageIndex(guest_address);
DEV_LOG("Page fault on protected RAM @ 0x{:08X} (page #{}), invalidating code cache.", guest_address, page_index); DEV_LOG("Page fault on protected RAM @ 0x{:08X} (page #{}), invalidating code cache.", guest_address, page_index);
@ -773,6 +786,14 @@ PageFaultHandler::HandlerResult PageFaultHandler::HandlePageFault(void* exceptio
return PageFaultHandler::HandlerResult::ContinueExecution; return PageFaultHandler::HandlerResult::ContinueExecution;
} }
// Fastmem exceptions should only occur within JIT code. Must also be on the core thread.
// If we're not, get out of here because it's probably a crash.
if (!CPU::CodeCache::IsInCodeBuffer(exception_pc))
return HandlerResult::ExecuteNextHandler;
// TODO: Remove the assertion eventually.
Assert(Host::IsOnCoreThread());
return CPU::CodeCache::HandleFastmemException(exception_pc, fault_address, is_write); return CPU::CodeCache::HandleFastmemException(exception_pc, fault_address, is_write);
} }

Loading…
Cancel
Save