mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-12 20:18:57 +02:00
[nce] Added case for access fault handling to manage page edge cases
This commit is contained in:
parent
32e63b5fa2
commit
1bdedc17ad
1 changed files with 21 additions and 5 deletions
|
|
@ -43,6 +43,7 @@ fpsimd_context* GetFloatingPointState(mcontext_t& host_ctx) {
|
|||
|
||||
using namespace Common::Literals;
|
||||
constexpr u32 StackSize = 128_KiB;
|
||||
constexpr u64 SplitPageAccessWindow = 64;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
@ -158,18 +159,33 @@ bool ArmNce::HandleGuestAlignmentFault(GuestContext* guest_ctx, void* raw_info,
|
|||
}
|
||||
|
||||
bool ArmNce::HandleGuestAccessFault(GuestContext* guest_ctx, void* raw_info, void* raw_context) {
|
||||
auto& host_ctx = static_cast<ucontext_t*>(raw_context)->uc_mcontext;
|
||||
auto* fpctx = GetFloatingPointState(host_ctx);
|
||||
auto* info = static_cast<siginfo_t*>(raw_info);
|
||||
|
||||
// Try to handle an invalid access.
|
||||
// TODO: handle accesses which split a page?
|
||||
const Common::ProcessAddress addr =
|
||||
(reinterpret_cast<u64>(info->si_addr) & ~Memory::YUZU_PAGEMASK);
|
||||
const u64 fault_addr = reinterpret_cast<u64>(info->si_addr);
|
||||
const Common::ProcessAddress addr = fault_addr & ~Memory::YUZU_PAGEMASK;
|
||||
const u64 page_offset = fault_addr & Memory::YUZU_PAGEMASK;
|
||||
auto& memory = guest_ctx->parent->m_running_thread->GetOwnerProcess()->GetMemory();
|
||||
if (memory.InvalidateNCE(addr, Memory::YUZU_PAGESIZE)) {
|
||||
bool handled = memory.InvalidateNCE(addr, Memory::YUZU_PAGESIZE);
|
||||
|
||||
if (page_offset < SplitPageAccessWindow && addr >= Memory::YUZU_PAGESIZE) {
|
||||
handled |= memory.InvalidateNCE(addr - Memory::YUZU_PAGESIZE, Memory::YUZU_PAGESIZE);
|
||||
}
|
||||
if (page_offset + SplitPageAccessWindow > Memory::YUZU_PAGESIZE) {
|
||||
handled |= memory.InvalidateNCE(addr + Memory::YUZU_PAGESIZE, Memory::YUZU_PAGESIZE);
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
// We handled the access successfully and are returning to guest code.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx); next_pc) {
|
||||
host_ctx.pc = *next_pc;
|
||||
return true;
|
||||
}
|
||||
|
||||
// We couldn't handle the access.
|
||||
return HandleFailedGuestFault(guest_ctx, raw_info, raw_context);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue