mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
vm: Fix possible IDM deadlock with Page Fault Notifications (partial)
This commit is contained in:
parent
6b0f7a8f55
commit
bb950cbb3b
6 changed files with 60 additions and 43 deletions
|
@ -24,13 +24,15 @@ error_code sys_cond_create(ppu_thread& ppu, vm::ptr<u32> cond_id, u32 mutex_id,
|
|||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (auto error = lv2_obj::create<lv2_cond>(attr->pshared, attr->ipc_key, attr->flags, [&]
|
||||
const auto _attr = *attr;
|
||||
|
||||
if (auto error = lv2_obj::create<lv2_cond>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]
|
||||
{
|
||||
return std::make_shared<lv2_cond>(
|
||||
attr->pshared,
|
||||
attr->flags,
|
||||
attr->ipc_key,
|
||||
attr->name_u64,
|
||||
_attr.pshared,
|
||||
_attr.flags,
|
||||
_attr.ipc_key,
|
||||
_attr.name_u64,
|
||||
std::move(mutex));
|
||||
}))
|
||||
{
|
||||
|
|
|
@ -24,7 +24,9 @@ error_code sys_event_flag_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<sys_e
|
|||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
const u32 protocol = attr->protocol;
|
||||
const auto _attr = *attr;
|
||||
|
||||
const u32 protocol = _attr.protocol;
|
||||
|
||||
if (protocol != SYS_SYNC_FIFO && protocol != SYS_SYNC_PRIORITY)
|
||||
{
|
||||
|
@ -32,7 +34,7 @@ error_code sys_event_flag_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<sys_e
|
|||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const u32 type = attr->type;
|
||||
const u32 type = _attr.type;
|
||||
|
||||
if (type != SYS_SYNC_WAITER_SINGLE && type != SYS_SYNC_WAITER_MULTIPLE)
|
||||
{
|
||||
|
@ -40,15 +42,15 @@ error_code sys_event_flag_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<sys_e
|
|||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (auto error = lv2_obj::create<lv2_event_flag>(attr->pshared, attr->ipc_key, attr->flags, [&]
|
||||
if (auto error = lv2_obj::create<lv2_event_flag>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]
|
||||
{
|
||||
return std::make_shared<lv2_event_flag>(
|
||||
attr->protocol,
|
||||
attr->pshared,
|
||||
attr->ipc_key,
|
||||
attr->flags,
|
||||
attr->type,
|
||||
attr->name_u64,
|
||||
_attr.protocol,
|
||||
_attr.pshared,
|
||||
_attr.ipc_key,
|
||||
_attr.flags,
|
||||
_attr.type,
|
||||
_attr.name_u64,
|
||||
init);
|
||||
}))
|
||||
{
|
||||
|
|
|
@ -22,7 +22,9 @@ error_code sys_mutex_create(ppu_thread& ppu, vm::ptr<u32> mutex_id, vm::ptr<sys_
|
|||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
switch (attr->protocol)
|
||||
const auto _attr = *attr;
|
||||
|
||||
switch (_attr.protocol)
|
||||
{
|
||||
case SYS_SYNC_FIFO: break;
|
||||
case SYS_SYNC_PRIORITY: break;
|
||||
|
@ -31,37 +33,37 @@ error_code sys_mutex_create(ppu_thread& ppu, vm::ptr<u32> mutex_id, vm::ptr<sys_
|
|||
break;
|
||||
default:
|
||||
{
|
||||
sys_mutex.error("sys_mutex_create(): unknown protocol (0x%x)", attr->protocol);
|
||||
sys_mutex.error("sys_mutex_create(): unknown protocol (0x%x)", _attr.protocol);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (attr->recursive)
|
||||
switch (_attr.recursive)
|
||||
{
|
||||
case SYS_SYNC_RECURSIVE: break;
|
||||
case SYS_SYNC_NOT_RECURSIVE: break;
|
||||
default:
|
||||
{
|
||||
sys_mutex.error("sys_mutex_create(): unknown recursive (0x%x)", attr->recursive);
|
||||
sys_mutex.error("sys_mutex_create(): unknown recursive (0x%x)", _attr.recursive);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (attr->adaptive != SYS_SYNC_NOT_ADAPTIVE)
|
||||
if (_attr.adaptive != SYS_SYNC_NOT_ADAPTIVE)
|
||||
{
|
||||
sys_mutex.todo("sys_mutex_create(): unexpected adaptive (0x%x)", attr->adaptive);
|
||||
sys_mutex.todo("sys_mutex_create(): unexpected adaptive (0x%x)", _attr.adaptive);
|
||||
}
|
||||
|
||||
if (auto error = lv2_obj::create<lv2_mutex>(attr->pshared, attr->ipc_key, attr->flags, [&]()
|
||||
if (auto error = lv2_obj::create<lv2_mutex>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]()
|
||||
{
|
||||
return std::make_shared<lv2_mutex>(
|
||||
attr->protocol,
|
||||
attr->recursive,
|
||||
attr->pshared,
|
||||
attr->adaptive,
|
||||
attr->ipc_key,
|
||||
attr->flags,
|
||||
attr->name_u64);
|
||||
_attr.protocol,
|
||||
_attr.recursive,
|
||||
_attr.pshared,
|
||||
_attr.adaptive,
|
||||
_attr.ipc_key,
|
||||
_attr.flags,
|
||||
_attr.name_u64);
|
||||
}))
|
||||
{
|
||||
return error;
|
||||
|
|
|
@ -364,6 +364,7 @@ error_code _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_par
|
|||
}
|
||||
|
||||
const ppu_func_opd_t entry = param->entry.opd();
|
||||
const u32 tls = param->tls;
|
||||
|
||||
// Clean some detached thread (hack)
|
||||
g_fxo->get<ppu_thread_cleaner>()->clean(0);
|
||||
|
@ -389,6 +390,13 @@ error_code _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_par
|
|||
|
||||
std::string ppu_name;
|
||||
|
||||
if (threadname)
|
||||
{
|
||||
constexpr u32 max_size = 27; // max size including null terminator
|
||||
const auto pname = threadname.get_ptr();
|
||||
ppu_name.assign(pname, std::find(pname, pname + max_size, '\0'));
|
||||
}
|
||||
|
||||
const u32 tid = idm::import<named_thread<ppu_thread>>([&]()
|
||||
{
|
||||
const u32 tid = idm::last_id();
|
||||
|
@ -397,10 +405,6 @@ error_code _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_par
|
|||
|
||||
if (threadname)
|
||||
{
|
||||
constexpr u32 max_size = 27; // max size including null terminator
|
||||
const auto pname = threadname.get_ptr();
|
||||
ppu_name.assign(pname, std::find(pname, pname + max_size, '\0'));
|
||||
|
||||
if (!ppu_name.empty())
|
||||
{
|
||||
fmt::append(full_name, " (%s)", ppu_name);
|
||||
|
@ -410,7 +414,7 @@ error_code _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_par
|
|||
ppu_thread_params p;
|
||||
p.stack_addr = stack_base;
|
||||
p.stack_size = stack_size;
|
||||
p.tls_addr = param->tls;
|
||||
p.tls_addr = tls;
|
||||
p.entry = entry;
|
||||
p.arg0 = arg;
|
||||
p.arg1 = unk;
|
||||
|
@ -426,7 +430,7 @@ error_code _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_par
|
|||
}
|
||||
|
||||
*thread_id = tid;
|
||||
sys_ppu_thread.warning(u8"_sys_ppu_thread_create(): Thread “%s” created (id=0x%x, func=*0x%x, rtoc=0x%x)", ppu_name, tid, entry.addr, entry.rtoc);
|
||||
sys_ppu_thread.warning(u8"_sys_ppu_thread_create(): Thread “%s” created (id=0x%x, func=*0x%x, rtoc=0x%x, user-tls=0x%x)", ppu_name, tid, entry.addr, entry.rtoc, tls);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,9 @@ error_code sys_rwlock_create(ppu_thread& ppu, vm::ptr<u32> rw_lock_id, vm::ptr<s
|
|||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
const u32 protocol = attr->protocol;
|
||||
const auto _attr = *attr;
|
||||
|
||||
const u32 protocol = _attr.protocol;
|
||||
|
||||
if (protocol == SYS_SYNC_PRIORITY_INHERIT)
|
||||
sys_rwlock.todo("sys_rwlock_create(): SYS_SYNC_PRIORITY_INHERIT");
|
||||
|
@ -33,9 +35,9 @@ error_code sys_rwlock_create(ppu_thread& ppu, vm::ptr<u32> rw_lock_id, vm::ptr<s
|
|||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (auto error = lv2_obj::create<lv2_rwlock>(attr->pshared, attr->ipc_key, attr->flags, [&]
|
||||
if (auto error = lv2_obj::create<lv2_rwlock>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]
|
||||
{
|
||||
return std::make_shared<lv2_rwlock>(protocol, attr->pshared, attr->ipc_key, attr->flags, attr->name_u64);
|
||||
return std::make_shared<lv2_rwlock>(protocol, _attr.pshared, _attr.ipc_key, _attr.flags, _attr.name_u64);
|
||||
}))
|
||||
{
|
||||
return error;
|
||||
|
|
|
@ -28,7 +28,9 @@ error_code sys_semaphore_create(ppu_thread& ppu, vm::ptr<u32> sem_id, vm::ptr<sy
|
|||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const u32 protocol = attr->protocol;
|
||||
const auto _attr = *attr;
|
||||
|
||||
const u32 protocol = _attr.protocol;
|
||||
|
||||
if (protocol != SYS_SYNC_FIFO && protocol != SYS_SYNC_PRIORITY)
|
||||
{
|
||||
|
@ -36,9 +38,9 @@ error_code sys_semaphore_create(ppu_thread& ppu, vm::ptr<u32> sem_id, vm::ptr<sy
|
|||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (auto error = lv2_obj::create<lv2_sema>(attr->pshared, attr->ipc_key, attr->flags, [&]
|
||||
if (auto error = lv2_obj::create<lv2_sema>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]
|
||||
{
|
||||
return std::make_shared<lv2_sema>(protocol, attr->pshared, attr->ipc_key, attr->flags, attr->name_u64, max_val, initial_val);
|
||||
return std::make_shared<lv2_sema>(protocol, _attr.pshared, _attr.ipc_key, _attr.flags, _attr.name_u64, max_val, initial_val);
|
||||
}))
|
||||
{
|
||||
return error;
|
||||
|
@ -268,13 +270,16 @@ error_code sys_semaphore_get_value(ppu_thread& ppu, u32 sem_id, vm::ptr<s32> cou
|
|||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
if (!idm::check<lv2_obj, lv2_sema>(sem_id, [=](lv2_sema& sema)
|
||||
const auto sema = idm::check<lv2_obj, lv2_sema>(sem_id, [](lv2_sema& sema)
|
||||
{
|
||||
*count = std::max<s32>(0, sema.val);
|
||||
}))
|
||||
return std::max<s32>(0, sema.val);
|
||||
});
|
||||
|
||||
if (!sema)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
*count = sema.ret;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue