diff --git a/rpcs3/Emu/Cell/lv2/sys_memory.cpp b/rpcs3/Emu/Cell/lv2/sys_memory.cpp index 6be2d593013f..007fe82a9212 100644 --- a/rpcs3/Emu/Cell/lv2/sys_memory.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_memory.cpp @@ -7,6 +7,9 @@ LOG_CHANNEL(sys_memory); +// +static shared_mutex s_memstats_mtx; + lv2_memory_alloca::lv2_memory_alloca(u32 size, u32 align, u64 flags, const std::shared_ptr& ct) : size(size) , align(align) @@ -202,6 +205,8 @@ error_code sys_memory_get_page_attribute(u32 addr, vm::ptr attr sys_memory.trace("sys_memory_get_page_attribute(addr=0x%x, attr=*0x%x)", addr, attr); + vm::reader_lock rlock; + if (!vm::check_addr(addr)) { return CELL_EINVAL; @@ -240,6 +245,8 @@ error_code sys_memory_get_user_memory_size(vm::ptr mem_info) // Get "default" memory container const auto dct = fxm::get(); + ::reader_lock lock(s_memstats_mtx); + mem_info->total_user_memory = dct->size; mem_info->available_user_memory = dct->size - dct->used; @@ -268,6 +275,8 @@ error_code sys_memory_container_create(vm::ptr cid, u32 size) const auto dct = fxm::get(); + std::lock_guard lock(s_memstats_mtx); + // Try to obtain "physical memory" from the default container if (!dct->take(size)) { @@ -286,6 +295,8 @@ error_code sys_memory_container_destroy(u32 cid) sys_memory.warning("sys_memory_container_destroy(cid=0x%x)", cid); + std::lock_guard lock(s_memstats_mtx); + const auto ct = idm::withdraw(cid, [](lv2_memory_container& ct) -> CellError { // Check if some memory is not deallocated (the container cannot be destroyed in this case) diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 85dd56d06ad9..ea25ab9aa0e5 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -514,9 +514,14 @@ namespace vm bool check_addr(u32 addr, u32 size, u8 flags) { - for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++) + for (u32 i = addr / 4096, max = static_cast((addr + u64{size} - 1) / 4096); i <= max; i++) { - if (UNLIKELY((g_pages[i % g_pages.size()].flags & flags) != flags)) + if (UNLIKELY(i >= g_pages.size())) + { + return false; + } + + if (UNLIKELY((g_pages[i].flags & flags) != flags)) { return false; }