anv: Fix a relocation race condition

Previously, we would read the offset from the BO in anv_reloc_list_add
to generate the presumed offset and then again in the caller to compute
the 64-bit address to write into the buffer.  However, if the offset
somehow changed between these two points, the presumed offset would no
longer match the written offset.  This is unlikely to actually ever be a
problem in practice because the presumed offset gets recorded first and
so if the written address is wrong then the presumed offset is almost
certainly wrong and the relocation will trigger.  However, it's much
safer to simply have anv_reloc_list_add return the 64-bit address.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
This commit is contained in:
Jason Ekstrand
2019-10-25 14:28:02 -05:00
parent bbf389013f
commit c4be72934e
4 changed files with 25 additions and 12 deletions

View File

@@ -57,17 +57,17 @@ blorp_surface_reloc(struct blorp_batch *batch, uint32_t ss_offset,
struct blorp_address address, uint32_t delta)
{
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
uint64_t address_u64 = 0;
VkResult result =
anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc,
ss_offset, address.buffer, address.offset + delta);
ss_offset, address.buffer, address.offset + delta,
&address_u64);
if (result != VK_SUCCESS)
anv_batch_set_error(&cmd_buffer->batch, result);
void *dest = anv_block_pool_map(
&cmd_buffer->device->surface_state_pool.block_pool, ss_offset);
uint64_t val = ((struct anv_bo*)address.buffer)->offset + address.offset +
delta;
write_reloc(cmd_buffer->device, dest, val, false);
write_reloc(cmd_buffer->device, dest, address_u64, false);
}
static uint64_t