diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index 86f82c8d01..5e92d2ff26 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -562,16 +562,39 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g sys_spu.warning("sys_spu_thread_initialize(thread=*0x%x, group=0x%x, spu_num=%d, img=*0x%x, attr=*0x%x, arg=*0x%x)", thread, group_id, spu_num, img, attr, arg); - const u32 option = attr->option; + if (!attr) + { + return CELL_EFAULT; + } - if (attr->name_len > 0x80 || option & ~(SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE | SYS_SPU_THREAD_OPTION_ASYNC_INTR_ENABLE)) + const sys_spu_thread_attribute attr_data = *attr; + + if (attr_data.name_len > 0x80) { return CELL_EINVAL; } - sys_spu_image image; + if (!arg) + { + return CELL_EFAULT; + } - switch (img->type) + const sys_spu_thread_argument args = *arg; + const u32 option = attr_data.option; + + if (option & ~(SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE | SYS_SPU_THREAD_OPTION_ASYNC_INTR_ENABLE)) + { + return CELL_EINVAL; + } + + if (!img) + { + return CELL_EFAULT; + } + + sys_spu_image image = *img; + + switch (image.type) { case SYS_SPU_IMAGE_TYPE_KERNEL: { @@ -591,12 +614,11 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g } case SYS_SPU_IMAGE_TYPE_USER: { - if (img->entry_point > 0x3fffc || img->nsegs <= 0 || img->nsegs > 0x20) + if (image.entry_point > 0x3fffc || image.nsegs <= 0 || image.nsegs > 0x20) { return CELL_EINVAL; } - image = *img; break; } default: return CELL_EINVAL; @@ -672,7 +694,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g } // Read thread name - const std::string thread_name(attr->name.get_ptr(), std::max(attr->name_len, 1) - 1); + const std::string thread_name(attr_data.name.get_ptr(), std::max(attr_data.name_len, 1) - 1); const auto group = idm::get(group_id); @@ -725,7 +747,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g ensure(vm::get(vm::spu)->falloc(spu->vm_offset(), SPU_LS_SIZE, &spu->shm, static_cast(vm::page_size_64k) | static_cast(vm::alloc_hidden))); spu->map_ls(*spu->shm, spu->ls); - group->args[inited] = {arg->arg1, arg->arg2, arg->arg3, arg->arg4}; + group->args[inited] = {args.arg1, args.arg2, args.arg3, args.arg4}; group->imgs[inited].first = image.entry_point; group->imgs[inited].second = std::move(spu_segs); @@ -800,12 +822,14 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr id, u32 num const s32 min_prio = g_ps3_process_info.has_root_perm() ? 0 : 16; - if (attr->nsize > 0x80 || !num) + const sys_spu_thread_group_attribute attr_data = *attr; + + if (attr_data.nsize > 0x80 || !num) { return CELL_EINVAL; } - const s32 type = attr->type; + const s32 type = attr_data.type; bool use_scheduler = true; bool use_memct = !!(type & SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER); @@ -902,7 +926,7 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr id, u32 num if (use_memct && mem_size) { - const auto sct = idm::get(attr->ct); + const auto sct = idm::get(attr_data.ct); if (!sct) { @@ -936,7 +960,7 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr id, u32 num return CELL_EBUSY; } - const auto group = idm::make_ptr(std::string(attr->name.get_ptr(), std::max(attr->nsize, 1) - 1), num, prio, type, ct, use_scheduler, mem_size); + const auto group = idm::make_ptr(std::string(attr_data.name.get_ptr(), std::max(attr_data.nsize, 1) - 1), num, prio, type, ct, use_scheduler, mem_size); if (!group) {