From 652d63eebbac2c5be7e4d8ae93b3fb11271a5a39 Mon Sep 17 00:00:00 2001 From: Eladash Date: Thu, 4 Jul 2019 21:27:06 +0300 Subject: [PATCH] Fix possible inconsistencies for sys_memory mem stats report --- rpcs3/Emu/Cell/lv2/sys_memory.cpp | 11 +++++++++++ rpcs3/Emu/Memory/vm.cpp | 10 ++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) 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..8f2e6a6709f4 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -514,9 +514,15 @@ namespace vm bool check_addr(u32 addr, u32 size, u8 flags) { - for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++) + // Overflow checking + if (addr + size < addr && (addr + size) != 0) + { + return false; + } + + for (u32 i = addr / 4096, max = (addr + size - 1) / 4096; i <= max; i++) { - if (UNLIKELY((g_pages[i % g_pages.size()].flags & flags) != flags)) + if (UNLIKELY((g_pages[i].flags & flags) != flags)) { return false; }