sys_spu: Fix sys_isolated_spu_create

This commit is contained in:
Elad 2026-04-25 02:44:21 +03:00
parent 9e0824112f
commit 7dce197ec4

View File

@ -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);