rsx: Implement crash-proofing for 308A_COLOR dst address

This commit is contained in:
Eladash 2021-08-13 19:24:50 +03:00 committed by kd-11
parent 24d7374a22
commit 2ce164be09
3 changed files with 37 additions and 17 deletions

View File

@ -74,7 +74,7 @@ namespace rsx
{
std::function<bool(u32 addr, bool is_writing)> g_access_violation_handler;
u32 get_address(u32 offset, u32 location, bool allow_failure, u32 line, u32 col, const char* file, const char* func)
u32 get_address(u32 offset, u32 location, u32 size_to_check, u32 line, u32 col, const char* file, const char* func)
{
const auto render = get_current_renderer();
std::string_view msg;
@ -84,7 +84,7 @@ namespace rsx
case CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER:
case CELL_GCM_LOCATION_LOCAL:
{
if (offset < render->local_mem_size)
if (offset < render->local_mem_size && render->local_mem_size - offset >= size_to_check)
{
return rsx::constants::local_mem_base + offset;
}
@ -98,7 +98,10 @@ namespace rsx
{
if (const u32 ea = render->iomap_table.get_addr(offset); ea + 1)
{
return ea;
if (!size_to_check || vm::check_addr(ea, 0, size_to_check))
{
return ea;
}
}
msg = "RSXIO memory not mapped!"sv;
@ -120,7 +123,10 @@ namespace rsx
{
if (const u32 ea = offset < 0x1000000 ? render->iomap_table.get_addr(0x0e000000 + offset) : -1; ea + 1)
{
return ea;
if (!size_to_check || vm::check_addr(ea, 0, size_to_check))
{
return ea;
}
}
msg = "RSXIO REPORT memory not mapped!"sv;
@ -181,8 +187,11 @@ namespace rsx
}
}
if (allow_failure)
if (size_to_check)
{
// Allow failure if specified size
// This is to allow accurate recovery for failures
rsx_log.warning("rsx::get_address(offset=0x%x, location=0x%x, size=0x%x): %s%s", offset, location, size_to_check, msg, src_loc{line, col, file, func});
return 0;
}

View File

@ -169,7 +169,7 @@ namespace rsx
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size);
u32 get_address(u32 offset, u32 location, bool allow_failure = false,
u32 get_address(u32 offset, u32 location, u32 size_to_check = 0,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),

View File

@ -925,8 +925,8 @@ namespace rsx
const u32 x = method_registers.nv308a_x() + index;
const u32 y = method_registers.nv308a_y();
// TODO
//auto res = vm::passive_lock(address, address + write_len);
// Skip "handled methods"
rsx->fifo_ctrl->skip_methods(count - 1);
switch (method_registers.blit_engine_nv3062_color_format())
{
@ -935,12 +935,21 @@ namespace rsx
{
// Bit cast - optimize to mem copy
const auto dst_address = get_address(dst_offset + (x * 4) + (out_pitch * y), dst_dma);
const u32 data_length = count * 4;
const auto dst_address = get_address(dst_offset + (x * 4) + (out_pitch * y), dst_dma, data_length);
if (!dst_address)
{
rsx->recover_fifo();
return;
}
const auto src_address = get_address(src_offset, CELL_GCM_LOCATION_MAIN);
const auto dst = vm::_ptr<u8>(dst_address);
const auto src = vm::_ptr<const u8>(src_address);
const u32 data_length = count * 4;
auto res = rsx::reservation_lock<true>(dst_address, data_length, src_address, data_length);
if (rsx->fifo_ctrl->last_cmd() & RSX_METHOD_NON_INCREMENT_CMD_MASK) [[unlikely]]
@ -969,12 +978,19 @@ namespace rsx
}
case blit_engine::transfer_destination_format::r5g6b5:
{
const auto dst_address = get_address(dst_offset + (x * 2) + (y * out_pitch), dst_dma);
const auto data_length = count * 2;
const auto dst_address = get_address(dst_offset + (x * 2) + (y * out_pitch), dst_dma, data_length);
const auto src_address = get_address(src_offset, CELL_GCM_LOCATION_MAIN);
const auto dst = vm::_ptr<u16>(dst_address);
const auto src = vm::_ptr<const u32>(src_address);
const auto data_length = count * 2;
if (!dst_address)
{
rsx->recover_fifo();
return;
}
auto res = rsx::reservation_lock<true>(dst_address, data_length, src_address, data_length);
auto convert = [](u32 input) -> u16
@ -1011,11 +1027,6 @@ namespace rsx
fmt::throw_exception("Unreachable");
}
}
//res->release(0);
// Skip "handled methods"
rsx->fifo_ctrl->skip_methods(count - 1);
}
};
}