mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-12-06 07:12:28 +01:00
vm/sys_memory: Remove VM locking in sys_memory_get_page_attribute
This commit is contained in:
parent
de914247be
commit
ddecade935
|
|
@ -5,6 +5,7 @@
|
|||
#include "Emu/CPU/CPUThread.h"
|
||||
#include "Emu/Cell/ErrorCodes.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/IdManager.h"
|
||||
|
||||
#include "util/asm.hpp"
|
||||
|
|
@ -249,17 +250,37 @@ error_code sys_memory_free(cpu_thread& cpu, u32 addr)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_memory_get_page_attribute(cpu_thread& cpu, u32 addr, vm::ptr<sys_page_attr_t> attr)
|
||||
error_code sys_memory_get_page_attribute(ppu_thread& ppu, u32 addr, vm::ptr<sys_page_attr_t> attr)
|
||||
{
|
||||
cpu.state += cpu_flag::wait;
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
sys_memory.trace("sys_memory_get_page_attribute(addr=0x%x, attr=*0x%x)", addr, attr);
|
||||
|
||||
vm::writer_lock rlock;
|
||||
|
||||
if (!vm::check_addr(addr) || addr >= SPU_FAKE_BASE_ADDR)
|
||||
if ((addr >> 28) == (ppu.stack_addr >> 28))
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
// Stack address: fast path
|
||||
if (!(addr >= ppu.stack_addr && addr < ppu.stack_addr + ppu.stack_size) && !vm::check_addr(addr))
|
||||
{
|
||||
return { CELL_EINVAL, addr };
|
||||
}
|
||||
|
||||
if (!vm::check_addr(attr.addr(), vm::page_readable, attr.size()))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
attr->attribute = 0x40000ull; // SYS_MEMORY_PROT_READ_WRITE
|
||||
attr->access_right = SYS_MEMORY_ACCESS_RIGHT_PPU_THR;
|
||||
attr->page_size = 4096;
|
||||
attr->pad = 0; // Always write 0
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
const auto [ok, vm_flags] = vm::get_addr_flags(addr);
|
||||
|
||||
if (!ok || addr >= SPU_FAKE_BASE_ADDR)
|
||||
{
|
||||
return { CELL_EINVAL, addr };
|
||||
}
|
||||
|
||||
if (!vm::check_addr(attr.addr(), vm::page_readable, attr.size()))
|
||||
|
|
@ -268,19 +289,20 @@ error_code sys_memory_get_page_attribute(cpu_thread& cpu, u32 addr, vm::ptr<sys_
|
|||
}
|
||||
|
||||
attr->attribute = 0x40000ull; // SYS_MEMORY_PROT_READ_WRITE (TODO)
|
||||
attr->access_right = addr >> 28 == 0xdu ? SYS_MEMORY_ACCESS_RIGHT_PPU_THR : SYS_MEMORY_ACCESS_RIGHT_ANY;// (TODO)
|
||||
attr->access_right = SYS_MEMORY_ACCESS_RIGHT_ANY; // TODO: Report accurately
|
||||
|
||||
if (vm::check_addr(addr, vm::page_1m_size))
|
||||
if (vm_flags & vm::page_1m_size)
|
||||
{
|
||||
attr->page_size = 0x100000;
|
||||
}
|
||||
else if (vm::check_addr(addr, vm::page_64k_size))
|
||||
else if (vm_flags & vm::page_64k_size)
|
||||
{
|
||||
attr->page_size = 0x10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
attr->page_size = 4096;
|
||||
//attr->page_size = 4096;
|
||||
fmt::throw_exception("Unreachable");
|
||||
}
|
||||
|
||||
attr->pad = 0; // Always write 0
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "Emu/Cell/ErrorCodes.h"
|
||||
|
||||
class cpu_thread;
|
||||
class ppu_thread;
|
||||
|
||||
enum lv2_mem_container_id : u32
|
||||
{
|
||||
|
|
@ -131,7 +132,7 @@ struct sys_memory_user_memory_stat_t
|
|||
error_code sys_memory_allocate(cpu_thread& cpu, u64 size, u64 flags, vm::ptr<u32> alloc_addr);
|
||||
error_code sys_memory_allocate_from_container(cpu_thread& cpu, u64 size, u32 cid, u64 flags, vm::ptr<u32> alloc_addr);
|
||||
error_code sys_memory_free(cpu_thread& cpu, u32 start_addr);
|
||||
error_code sys_memory_get_page_attribute(cpu_thread& cpu, u32 addr, vm::ptr<sys_page_attr_t> attr);
|
||||
error_code sys_memory_get_page_attribute(ppu_thread& cpu, u32 addr, vm::ptr<sys_page_attr_t> attr);
|
||||
error_code sys_memory_get_user_memory_size(cpu_thread& cpu, vm::ptr<sys_memory_info_t> mem_info);
|
||||
error_code sys_memory_get_user_memory_stat(cpu_thread& cpu, vm::ptr<sys_memory_user_memory_stat_t> mem_stat);
|
||||
error_code sys_memory_container_create(cpu_thread& cpu, vm::ptr<u32> cid, u64 size);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ namespace vm
|
|||
bool check_addr(u32 addr, u8 flags, u32 size);
|
||||
|
||||
template <u32 Size = 1>
|
||||
bool check_addr(u32 addr, u8 flags = page_readable)
|
||||
inline bool check_addr(u32 addr, u8 flags = page_readable)
|
||||
{
|
||||
extern std::array<memory_page, 0x100000000 / 4096> g_pages;
|
||||
|
||||
|
|
@ -94,6 +94,16 @@ namespace vm
|
|||
return !(~g_pages[addr / 4096] & (flags | page_allocated));
|
||||
}
|
||||
|
||||
// Like check_addr but should only be used in lock-free context with care
|
||||
inline std::pair<bool, u8> get_addr_flags(u32 addr) noexcept
|
||||
{
|
||||
extern std::array<memory_page, 0x100000000 / 4096> g_pages;
|
||||
|
||||
const u8 flags = g_pages[addr / 4096].load();
|
||||
|
||||
return std::make_pair(!!(flags & page_allocated), flags);
|
||||
}
|
||||
|
||||
// Read string in a safe manner (page aware) (bool true = if null-termination)
|
||||
bool read_string(u32 addr, u32 max_size, std::string& out_string, bool check_pages = true) noexcept;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue