mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 20:15:27 +00:00
sys_lwcond: Extract protocol from lwmutex at creation
This is the only reason theres a need to specify lwmutex_sq id at creation. unlike sys_cond, lwcond isn't connected to lwmutex at the lv2 level. SYS_SYNC_RETRY fix is done explicitly at the firmware level. This fixes issues when the original lwcond and lwmutexol data got corrupted or deallocated, this can happen when the program simply memcpy the control data to somewhere else. Or if it uses direct lv2 the lwcond conrol param can even be NULL which will make it access violate when dereferncing it. (This param is unchecked and can be anything)
This commit is contained in:
parent
7508ae6e65
commit
e40b76b253
2 changed files with 19 additions and 6 deletions
|
@ -16,13 +16,24 @@ error_code _sys_lwcond_create(ppu_thread& ppu, vm::ptr<u32> lwcond_id, u32 lwmut
|
|||
|
||||
sys_lwcond.warning("_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=0x%x, control=*0x%x, name=0x%llx, arg5=0x%x)", lwcond_id, lwmutex_id, control, name, arg5);
|
||||
|
||||
// Temporarily
|
||||
if (!idm::check<lv2_obj, lv2_lwmutex>(lwmutex_id))
|
||||
u32 protocol;
|
||||
|
||||
// Extract protocol from lwmutex
|
||||
if (!idm::check<lv2_obj, lv2_lwmutex>(lwmutex_id, [&protocol](lv2_lwmutex& mutex)
|
||||
{
|
||||
protocol = mutex.protocol;
|
||||
}))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (const u32 id = idm::make<lv2_obj, lv2_lwcond>(name, lwmutex_id, control))
|
||||
if (protocol == SYS_SYNC_RETRY)
|
||||
{
|
||||
// Lwcond can't have SYS_SYNC_RETRY protocol
|
||||
protocol = SYS_SYNC_PRIORITY;
|
||||
}
|
||||
|
||||
if (const u32 id = idm::make<lv2_obj, lv2_lwcond>(name, lwmutex_id, protocol, control))
|
||||
{
|
||||
*lwcond_id = id;
|
||||
return CELL_OK;
|
||||
|
@ -114,7 +125,7 @@ error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u3
|
|||
}
|
||||
else
|
||||
{
|
||||
result = cond.schedule<ppu_thread>(cond.sq, cond.control->lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK);
|
||||
result = cond.schedule<ppu_thread>(cond.sq, cond.protocol);
|
||||
}
|
||||
|
||||
if (result)
|
||||
|
@ -206,7 +217,7 @@ error_code _sys_lwcond_signal_all(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
|
|||
|
||||
u32 result = 0;
|
||||
|
||||
while (const auto cpu = cond.schedule<ppu_thread>(cond.sq, cond.control->lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK))
|
||||
while (const auto cpu = cond.schedule<ppu_thread>(cond.sq, cond.protocol))
|
||||
{
|
||||
cond.waiters--;
|
||||
|
||||
|
|
|
@ -27,15 +27,17 @@ struct lv2_lwcond final : lv2_obj
|
|||
|
||||
const u64 name;
|
||||
const u32 lwid;
|
||||
const u32 protocol;
|
||||
vm::ptr<sys_lwcond_t> control;
|
||||
|
||||
shared_mutex mutex;
|
||||
atomic_t<u32> waiters{0};
|
||||
std::deque<cpu_thread*> sq;
|
||||
|
||||
lv2_lwcond(u64 name, u32 lwid, vm::ptr<sys_lwcond_t> control)
|
||||
lv2_lwcond(u64 name, u32 lwid, u32 protocol, vm::ptr<sys_lwcond_t> control)
|
||||
: name(name)
|
||||
, lwid(lwid)
|
||||
, protocol(protocol)
|
||||
, control(control)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue