mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-20 03:17:02 +02:00
[nce] Added "tainted" page fault handling inside dual channel
This commit is contained in:
parent
b7087a16ba
commit
ca42578d4e
2 changed files with 30 additions and 2 deletions
|
|
@ -44,6 +44,7 @@ fpsimd_context* GetFloatingPointState(mcontext_t& host_ctx) {
|
||||||
using namespace Common::Literals;
|
using namespace Common::Literals;
|
||||||
constexpr u32 StackSize = 128_KiB;
|
constexpr u32 StackSize = 128_KiB;
|
||||||
constexpr u64 SplitPageAccessWindow = 64;
|
constexpr u64 SplitPageAccessWindow = 64;
|
||||||
|
constexpr size_t MaxPreciseAccessPages = 256;
|
||||||
|
|
||||||
[[nodiscard]] constexpr u64 AlignDownPage(u64 addr) {
|
[[nodiscard]] constexpr u64 AlignDownPage(u64 addr) {
|
||||||
return addr & ~u64{Memory::YUZU_PAGEMASK};
|
return addr & ~u64{Memory::YUZU_PAGEMASK};
|
||||||
|
|
@ -191,15 +192,18 @@ bool ArmNce::HandleGuestAccessFault(GuestContext* guest_ctx, void* raw_info, voi
|
||||||
auto& host_ctx = static_cast<ucontext_t*>(raw_context)->uc_mcontext;
|
auto& host_ctx = static_cast<ucontext_t*>(raw_context)->uc_mcontext;
|
||||||
auto* fpctx = GetFloatingPointState(host_ctx);
|
auto* fpctx = GetFloatingPointState(host_ctx);
|
||||||
auto* info = static_cast<siginfo_t*>(raw_info);
|
auto* info = static_cast<siginfo_t*>(raw_info);
|
||||||
|
auto* parent = guest_ctx->parent;
|
||||||
|
|
||||||
const u64 fault_addr = reinterpret_cast<u64>(info->si_addr);
|
const u64 fault_addr = reinterpret_cast<u64>(info->si_addr);
|
||||||
const Common::ProcessAddress addr = fault_addr & ~Memory::YUZU_PAGEMASK;
|
const Common::ProcessAddress addr = fault_addr & ~Memory::YUZU_PAGEMASK;
|
||||||
const u64 page_offset = fault_addr & Memory::YUZU_PAGEMASK;
|
const u64 page_offset = fault_addr & Memory::YUZU_PAGEMASK;
|
||||||
auto& memory = guest_ctx->parent->m_running_thread->GetOwnerProcess()->GetMemory();
|
auto& memory = parent->m_running_thread->GetOwnerProcess()->GetMemory();
|
||||||
const bool prefer_precise_channel = ShouldUsePreciseAccessChannel(guest_ctx, fault_addr);
|
const bool prefer_precise_channel = ShouldUsePreciseAccessChannel(guest_ctx, fault_addr) ||
|
||||||
|
parent->IsPreciseAccessPage(fault_addr);
|
||||||
|
|
||||||
if (prefer_precise_channel) {
|
if (prefer_precise_channel) {
|
||||||
if (auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx); next_pc) {
|
if (auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx); next_pc) {
|
||||||
|
parent->MarkPreciseAccessPage(fault_addr);
|
||||||
host_ctx.pc = *next_pc;
|
host_ctx.pc = *next_pc;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -220,6 +224,7 @@ bool ArmNce::HandleGuestAccessFault(GuestContext* guest_ctx, void* raw_info, voi
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx); next_pc) {
|
if (auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx); next_pc) {
|
||||||
|
parent->MarkPreciseAccessPage(fault_addr);
|
||||||
host_ctx.pc = *next_pc;
|
host_ctx.pc = *next_pc;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -236,6 +241,19 @@ void ArmNce::HandleHostAccessFault(int sig, void* raw_info, void* raw_context) {
|
||||||
return g_orig_segv_action.sa_sigaction(sig, static_cast<siginfo_t*>(raw_info), raw_context);
|
return g_orig_segv_action.sa_sigaction(sig, static_cast<siginfo_t*>(raw_info), raw_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ArmNce::IsPreciseAccessPage(u64 addr) const {
|
||||||
|
const std::scoped_lock lk{m_precise_pages_guard};
|
||||||
|
return m_precise_pages.contains(AlignDownPage(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArmNce::MarkPreciseAccessPage(u64 addr) {
|
||||||
|
const std::scoped_lock lk{m_precise_pages_guard};
|
||||||
|
if (m_precise_pages.size() >= MaxPreciseAccessPages) {
|
||||||
|
m_precise_pages.clear();
|
||||||
|
}
|
||||||
|
m_precise_pages.insert(AlignDownPage(addr));
|
||||||
|
}
|
||||||
|
|
||||||
void ArmNce::LockThread(Kernel::KThread* thread) {
|
void ArmNce::LockThread(Kernel::KThread* thread) {
|
||||||
auto* thread_params = &thread->GetNativeExecutionParameters();
|
auto* thread_params = &thread->GetNativeExecutionParameters();
|
||||||
LockThreadParameters(thread_params);
|
LockThreadParameters(thread_params);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/arm/nce/guest_context.h"
|
#include "core/arm/nce/guest_context.h"
|
||||||
|
|
@ -77,6 +81,9 @@ private:
|
||||||
static void HandleHostAlignmentFault(int sig, void* info, void* raw_context);
|
static void HandleHostAlignmentFault(int sig, void* info, void* raw_context);
|
||||||
static void HandleHostAccessFault(int sig, void* info, void* raw_context);
|
static void HandleHostAccessFault(int sig, void* info, void* raw_context);
|
||||||
|
|
||||||
|
bool IsPreciseAccessPage(u64 addr) const;
|
||||||
|
void MarkPreciseAccessPage(u64 addr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Core::System& m_system;
|
Core::System& m_system;
|
||||||
|
|
||||||
|
|
@ -88,6 +95,9 @@ public:
|
||||||
GuestContext m_guest_ctx{};
|
GuestContext m_guest_ctx{};
|
||||||
Kernel::KThread* m_running_thread{};
|
Kernel::KThread* m_running_thread{};
|
||||||
|
|
||||||
|
mutable std::mutex m_precise_pages_guard{};
|
||||||
|
std::unordered_set<u64> m_precise_pages{};
|
||||||
|
|
||||||
// Stack for signal processing.
|
// Stack for signal processing.
|
||||||
std::unique_ptr<u8[]> m_stack{};
|
std::unique_ptr<u8[]> m_stack{};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue