mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-04-29 23:41:12 -06:00
sys_spu: Fix sys_isolated_spu_create
This commit is contained in:
parent
9e0824112f
commit
7dce197ec4
@ -145,13 +145,34 @@ void sys_spu_image::deploy(u8* loc, std::span<const sys_spu_segment> segs, bool
|
||||
|
||||
sha1_update(&sha, reinterpret_cast<const uchar*>(&seg.type), sizeof(seg.type));
|
||||
|
||||
// Prevent possible segfault
|
||||
const u32 masked_ls = seg.ls % SPU_LS_SIZE;
|
||||
u32 masked_size = std::min<u32>(SPU_LS_SIZE - masked_ls, seg.size % SPU_LS_SIZE);
|
||||
|
||||
// Hash big-endian values
|
||||
if (seg.type == SYS_SPU_SEGMENT_TYPE_COPY)
|
||||
{
|
||||
std::memcpy(loc + seg.ls, vm::base(seg.addr), seg.size);
|
||||
if (!vm::check_addr(seg.addr, 0, seg.size))
|
||||
{
|
||||
// Further clamp size to fit 4GB address space, preventing segfault
|
||||
masked_size = masked_size ? std::min<u32>(u32{umax} - seg.addr, masked_size - 1) + 1 : 0;
|
||||
spu_log.error("Dumping sys_spu_image log - illgal address:\n\n%s", dump);
|
||||
}
|
||||
|
||||
if ((seg.ls | seg.size) % 4)
|
||||
{
|
||||
spu_log.error("Unaligned SPU COPY type segment (ls=0x%x, size=0x%x)", seg.ls, seg.size);
|
||||
}
|
||||
|
||||
if (masked_ls != seg.ls || masked_size != seg.size)
|
||||
{
|
||||
spu_log.error("Illegal SPU COPY type segment (ls=0x%x, size=0x%x)", seg.ls, seg.size);
|
||||
}
|
||||
|
||||
std::memcpy(loc + masked_ls, vm::base(seg.addr), masked_size);
|
||||
sha1_update(&sha, reinterpret_cast<const uchar*>(&seg.size), sizeof(seg.size));
|
||||
sha1_update(&sha, reinterpret_cast<const uchar*>(&seg.ls), sizeof(seg.ls));
|
||||
sha1_update(&sha, vm::_ptr<uchar>(seg.addr), seg.size);
|
||||
sha1_update(&sha, loc + masked_ls, masked_size);
|
||||
}
|
||||
else if (seg.type == SYS_SPU_SEGMENT_TYPE_FILL)
|
||||
{
|
||||
@ -160,7 +181,12 @@ void sys_spu_image::deploy(u8* loc, std::span<const sys_spu_segment> segs, bool
|
||||
spu_log.error("Unaligned SPU FILL type segment (ls=0x%x, size=0x%x)", seg.ls, seg.size);
|
||||
}
|
||||
|
||||
std::fill_n(reinterpret_cast<be_t<u32>*>(loc + seg.ls), seg.size / 4, seg.addr);
|
||||
if (masked_ls != seg.ls || masked_size != seg.size)
|
||||
{
|
||||
spu_log.error("Illegal SPU FILL type segment (ls=0x%x, size=0x%x)", seg.ls, seg.size);
|
||||
}
|
||||
|
||||
std::fill_n(reinterpret_cast<be_t<u32>*>(loc + masked_ls), masked_size / 4, seg.addr);
|
||||
sha1_update(&sha, reinterpret_cast<const uchar*>(&seg.size), sizeof(seg.size));
|
||||
sha1_update(&sha, reinterpret_cast<const uchar*>(&seg.ls), sizeof(seg.ls));
|
||||
sha1_update(&sha, reinterpret_cast<const uchar*>(&seg.addr), sizeof(seg.addr));
|
||||
@ -2517,6 +2543,9 @@ error_code sys_isolated_spu_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<voi
|
||||
|
||||
const auto thread = idm::make_ptr<named_thread<spu_thread>>(nullptr, index, "", index, true);
|
||||
|
||||
ensure(vm::get(vm::spu)->falloc(thread->vm_offset(), SPU_LS_SIZE, &thread->shm, vm::page_size_64k));
|
||||
thread->map_ls(*thread->shm, thread->ls);
|
||||
|
||||
thread->gpr[3] = v128::from64(0, arg1);
|
||||
thread->gpr[4] = v128::from64(0, arg2);
|
||||
thread->gpr[5] = v128::from64(0, arg3);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user