mirror of
https://github.com/Vita3K/Vita3K.git
synced 2026-07-11 01:34:23 +02:00
Address PR review: JIT cache invalidation + kernel.mutex locking
- SceCpuForDriver: ksceKernelCpuIcacheInvalidateRange and ksceKernelCpuIcacheAndL2WritebackInvalidateRange now call invalidate_jit_cache() to properly invalidate dynarmic's JIT cache - taiHEN: All loaded_modules accesses now protected by kernel.mutex using scoped locks to avoid deadlocks with state->mutex and export_nids_mutex (lock order: kernel.mutex -> export_nids_mutex -> state->mutex)
This commit is contained in:
Vendored
+1
-1
Submodule external/substitute updated: e9f3276299...319da6b563
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <module/module.h>
|
||||
|
||||
#include <cpu/functions.h>
|
||||
#include <kernel/state.h>
|
||||
#include <kernel/types.h>
|
||||
|
||||
#include <cstring>
|
||||
@@ -351,11 +353,13 @@ EXPORT(int, ksceKernelCpuDcacheWritebackInvalidateRange) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, ksceKernelCpuIcacheInvalidateRange) {
|
||||
EXPORT(int, ksceKernelCpuIcacheInvalidateRange, Address addr, uint32_t size) {
|
||||
emuenv.kernel.invalidate_jit_cache(addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, ksceKernelCpuIcacheAndL2WritebackInvalidateRange) {
|
||||
EXPORT(int, ksceKernelCpuIcacheAndL2WritebackInvalidateRange, Address addr, uint32_t size) {
|
||||
emuenv.kernel.invalidate_jit_cache(addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -547,6 +547,7 @@ EXPORT(SceUID, taiHookFunctionImportForUser, Ptr<uint32_t> p_hook, Ptr<void> arg
|
||||
// Find the import stub for this NID in the specified module
|
||||
Address stub_addr;
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const std::lock_guard<std::mutex> guard(emuenv.kernel.export_nids_mutex);
|
||||
stub_addr = find_import_stub_in_module(emuenv, module_name, func_nid);
|
||||
}
|
||||
@@ -585,6 +586,9 @@ EXPORT(SceUID, taiHookFunctionOffsetForUser, Ptr<uint32_t> p_hook, Ptr<void> arg
|
||||
Address hook_func = oargs->hook_func;
|
||||
|
||||
// Find the target address from module + segment + offset
|
||||
Address target_addr;
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const auto mod_it = emuenv.kernel.loaded_modules.find(modid);
|
||||
if (mod_it == emuenv.kernel.loaded_modules.end()) {
|
||||
LOG_WARN("taiHookFunctionOffsetForUser: module {} not found", modid);
|
||||
@@ -596,7 +600,8 @@ EXPORT(SceUID, taiHookFunctionOffsetForUser, Ptr<uint32_t> p_hook, Ptr<void> arg
|
||||
return SCE_KERNEL_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
Address target_addr = mod.segments[segidx].vaddr.address() + offset;
|
||||
target_addr = mod.segments[segidx].vaddr.address() + offset;
|
||||
}
|
||||
// Add Thumb bit if the thumb flag is set
|
||||
if (thumb)
|
||||
target_addr |= 1;
|
||||
@@ -637,6 +642,8 @@ EXPORT(int, taiGetModuleInfo, const char *module, Ptr<void> info) {
|
||||
};
|
||||
|
||||
// Search LLE loaded modules first
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const auto &loaded_modules = emuenv.kernel.loaded_modules;
|
||||
for (const auto &[uid, mod] : loaded_modules) {
|
||||
if (std::string(mod->info.module_name) == module) {
|
||||
@@ -658,6 +665,7 @@ EXPORT(int, taiGetModuleInfo, const char *module, Ptr<void> info) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For HLE modules (SceSysmem etc), return a synthetic entry.
|
||||
// Plugins may look these up to patch them, but in the emulator HLE modules
|
||||
@@ -805,6 +813,9 @@ EXPORT(SceUID, taiInjectDataForUser, Ptr<void> args) {
|
||||
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
|
||||
|
||||
// Resolve module + segment + offset to address
|
||||
Address dest_addr;
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const auto mod_it = emuenv.kernel.loaded_modules.find(modid);
|
||||
if (mod_it == emuenv.kernel.loaded_modules.end()) {
|
||||
LOG_WARN("taiInjectDataForUser: module {} not found", modid);
|
||||
@@ -816,7 +827,8 @@ EXPORT(SceUID, taiInjectDataForUser, Ptr<void> args) {
|
||||
return SCE_KERNEL_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
Address dest_addr = mod.segments[segidx].vaddr.address() + offset;
|
||||
dest_addr = mod.segments[segidx].vaddr.address() + offset;
|
||||
}
|
||||
Ptr<void> dest(dest_addr);
|
||||
|
||||
// Delegate to taiInjectAbs logic
|
||||
@@ -888,10 +900,13 @@ EXPORT(SceUID, taiLoadStartKernelModuleForUser, const char *path, Ptr<void> args
|
||||
if (uid < 0)
|
||||
return uid;
|
||||
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const auto mod_it = emuenv.kernel.loaded_modules.find(uid);
|
||||
if (mod_it != emuenv.kernel.loaded_modules.end()) {
|
||||
start_module(emuenv, mod_it->second->info);
|
||||
}
|
||||
}
|
||||
return uid;
|
||||
}
|
||||
|
||||
@@ -904,10 +919,13 @@ EXPORT(SceUID, taiLoadStartModuleForPidForUser, const char *path, Ptr<void> args
|
||||
if (uid < 0)
|
||||
return uid;
|
||||
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const auto mod_it = emuenv.kernel.loaded_modules.find(uid);
|
||||
if (mod_it != emuenv.kernel.loaded_modules.end()) {
|
||||
start_module(emuenv, mod_it->second->info);
|
||||
}
|
||||
}
|
||||
return uid;
|
||||
}
|
||||
|
||||
@@ -1006,6 +1024,7 @@ EXPORT(SceUID, taiHookFunctionImportForKernel, SceUID pid, Ptr<uint32_t> p_hook,
|
||||
|
||||
Address stub_addr;
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const std::lock_guard<std::mutex> guard(emuenv.kernel.export_nids_mutex);
|
||||
stub_addr = find_import_stub_in_module(emuenv, module, import_func_nid);
|
||||
}
|
||||
@@ -1036,6 +1055,9 @@ EXPORT(SceUID, taiHookFunctionOffsetForKernel, SceUID pid, Ptr<uint32_t> p_hook,
|
||||
if (!state)
|
||||
return SCE_KERNEL_ERROR_ERROR;
|
||||
|
||||
Address target_addr;
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const auto mod_it = emuenv.kernel.loaded_modules.find(modid);
|
||||
if (mod_it == emuenv.kernel.loaded_modules.end()) {
|
||||
LOG_WARN("taiHookFunctionOffsetForKernel: module {} not found", modid);
|
||||
@@ -1046,7 +1068,8 @@ EXPORT(SceUID, taiHookFunctionOffsetForKernel, SceUID pid, Ptr<uint32_t> p_hook,
|
||||
if (segidx < 0 || segidx >= MODULE_INFO_NUM_SEGMENTS || mod.segments[segidx].memsz == 0)
|
||||
return SCE_KERNEL_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
Address target_addr = mod.segments[segidx].vaddr.address() + offset;
|
||||
target_addr = mod.segments[segidx].vaddr.address() + offset;
|
||||
}
|
||||
target_addr &= ~1u; // Clear thumb bit
|
||||
|
||||
const std::lock_guard<std::mutex> lock(state->mutex);
|
||||
@@ -1081,6 +1104,9 @@ EXPORT(SceUID, taiInjectDataForKernel, SceUID pid, SceUID modid, int segidx, uin
|
||||
if (!data || size == 0)
|
||||
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
|
||||
|
||||
Address dest_addr;
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const auto mod_it = emuenv.kernel.loaded_modules.find(modid);
|
||||
if (mod_it == emuenv.kernel.loaded_modules.end()) {
|
||||
LOG_WARN("taiInjectDataForKernel: module {} not found", modid);
|
||||
@@ -1091,7 +1117,8 @@ EXPORT(SceUID, taiInjectDataForKernel, SceUID pid, SceUID modid, int segidx, uin
|
||||
if (segidx < 0 || segidx >= MODULE_INFO_NUM_SEGMENTS || mod.segments[segidx].memsz == 0)
|
||||
return SCE_KERNEL_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
Address dest_addr = mod.segments[segidx].vaddr.address() + offset;
|
||||
dest_addr = mod.segments[segidx].vaddr.address() + offset;
|
||||
}
|
||||
Ptr<void> dest(dest_addr);
|
||||
|
||||
return export_taiInjectAbs(emuenv, thread_id, export_name, dest, Ptr<const void>(data.address()), size);
|
||||
@@ -1121,6 +1148,9 @@ EXPORT(int, module_get_offset, SceUID pid, SceUID modid, int segidx, uint32_t of
|
||||
if (!addr)
|
||||
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
|
||||
|
||||
Address result;
|
||||
{
|
||||
const std::lock_guard<std::mutex> kernel_lock(emuenv.kernel.mutex);
|
||||
const auto mod_it = emuenv.kernel.loaded_modules.find(modid);
|
||||
if (mod_it == emuenv.kernel.loaded_modules.end()) {
|
||||
LOG_DEBUG("module_get_offset: module {} not found (may be HLE)", modid);
|
||||
@@ -1132,7 +1162,8 @@ EXPORT(int, module_get_offset, SceUID pid, SceUID modid, int segidx, uint32_t of
|
||||
return SCE_KERNEL_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
Address result = mod.segments[segidx].vaddr.address() + offset;
|
||||
result = mod.segments[segidx].vaddr.address() + offset;
|
||||
}
|
||||
*addr.get(emuenv.mem) = result;
|
||||
|
||||
LOG_DEBUG("module_get_offset: mod={} seg={} off={} -> {}", modid, segidx, log_hex(offset), log_hex(result));
|
||||
|
||||
Reference in New Issue
Block a user