diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 928f19a1ac..5d7beb4145 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -3944,19 +3944,23 @@ s64 spu_thread::get_ch_value(u32 ch) state += cpu_flag::wait; - using resrv_ptr = std::add_pointer_t; + using resrv_ptr = std::add_pointer_t; - resrv_ptr resrv_mem{}; + resrv_ptr resrv_mem = vm::get_super_ptr(raddr); std::shared_ptr rdata_shm; - if (raddr && mask1 & SPU_EVENT_LR) + // Does not need to safe-access reservation if LR is the only event masked + // Because it's either an access violation or a livelock if an invalid memory is passed + if (raddr && mask1 > SPU_EVENT_LR) { auto area = vm::get(vm::any, raddr); - if (area && (area->flags & vm::preallocated) && vm::check_addr(raddr)) + if (area && (area->flags & vm::preallocated)) { - // Obtain pointer to pre-allocated storage - resrv_mem = vm::get_super_ptr(raddr); + if (!vm::check_addr(raddr)) + { + resrv_mem = nullptr; + } } else if (area) { @@ -3967,7 +3971,7 @@ s64 spu_thread::get_ch_value(u32 ch) { const u32 data_offs = raddr - base_addr; rdata_shm = std::move(shm_); - vm::writer_lock{}, resrv_mem = reinterpret_cast(rdata_shm->map_self() + data_offs); + resrv_mem = reinterpret_cast(rdata_shm->get() + data_offs); } } diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 0597ded6dd..b750d86f5b 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -698,7 +698,7 @@ namespace vm { utils::memory_protect(g_base_addr + addr, size, prot); } - else if (shm->map_critical(g_base_addr + addr, prot) != g_base_addr + addr || shm->map_critical(g_sudo_addr + addr) != g_sudo_addr + addr) + else if (shm->map_critical(g_base_addr + addr, prot) != g_base_addr + addr || shm->map_critical(g_sudo_addr + addr) != g_sudo_addr + addr || !shm->map_self()) { fmt::throw_exception("Memory mapping failed - blame Windows (addr=0x%x, size=0x%x, flags=0x%x)", addr, size, flags); }