anv: don't relocate memory from blob
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

This could override data allocated by the application when shader code
is loaded from binary in vkCreateShaderObjectEXT().

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: d39e443ef8 ("anv: add infrastructure for common vk_pipeline")
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40727>
This commit is contained in:
Lionel Landwerlin 2026-02-05 10:10:09 +02:00 committed by Marge Bot
parent 283f07f13e
commit 21952ffb07
2 changed files with 57 additions and 20 deletions

View file

@ -1314,6 +1314,12 @@ struct anv_shader_group_rt_replay {
struct anv_shader {
struct vk_shader vk;
/**
* Code of the shader on the host
*
* This is before relocations are applied so that can always return the
* same blob of data for serialization.
*/
void *code;
struct anv_shader_alloc kernel;

View file

@ -548,35 +548,59 @@ anv_shader_set_relocs(struct anv_device *device,
return rv_count;
}
struct anv_shader_reloc {
struct anv_device *device;
const VkAllocationCallbacks *alloc;
const void *in_code;
uint32_t *code_size;
void *relocated_code;
};
static VkResult
anv_shader_reloc(struct anv_device *device,
void *code,
struct anv_shader *shader,
const VkAllocationCallbacks *pAllocator)
anv_shader_reloc_begin(struct anv_shader_reloc *reloc,
struct anv_device *device,
const void *in_code,
struct anv_shader *shader,
const VkAllocationCallbacks *alloc)
{
memset(reloc, 0, sizeof(*reloc));
reloc->device = device;
reloc->alloc = alloc;
const uint32_t max_relocs =
BRW_SHADER_RELOC_EMBEDDED_SAMPLER_HANDLE +
shader->bind_map.embedded_sampler_count;
uint32_t rv_count;
struct intel_shader_reloc_value *reloc_values =
vk_zalloc2(&device->vk.alloc, pAllocator,
sizeof(struct intel_shader_reloc_value) * max_relocs, 8,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
if (reloc_values == NULL)
VK_MULTIALLOC(ma);
VK_MULTIALLOC_DECL_SIZE(&ma, void, code, shader->prog_data->program_size);
VK_MULTIALLOC_DECL(&ma, struct intel_shader_reloc_value, reloc_values, max_relocs);
if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, alloc,
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE))
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
rv_count = anv_shader_set_relocs(device, reloc_values, shader);
/* Make a copy of the code to relocate it, we don't know where the data
* comes from, could be read-only, could app-managed, ...
*/
reloc->relocated_code = code;
memcpy(reloc->relocated_code, in_code, shader->prog_data->program_size);
uint32_t rv_count = anv_shader_set_relocs(device, reloc_values, shader);
assert(rv_count <= max_relocs);
brw_write_shader_relocs(&device->physical->compiler->isa,
code, shader->prog_data,
reloc->relocated_code, shader->prog_data,
reloc_values, rv_count);
vk_free2(&device->vk.alloc, pAllocator, reloc_values);
return VK_SUCCESS;
}
static void
anv_shader_reloc_end(struct anv_shader_reloc *reloc)
{
vk_free2(&reloc->device->vk.alloc, reloc->alloc, reloc->relocated_code);
}
struct internal_representation {
char *nir_str;
uint32_t nir_str_len;
@ -712,16 +736,20 @@ anv_shader_create(struct anv_device *device,
shader->instance_multiplier = shader_data->instance_multiplier;
result = anv_shader_reloc(device, shader_data->code, shader, pAllocator);
struct anv_shader_reloc reloc;
result = anv_shader_reloc_begin(&reloc, device, shader_data->code,
shader, pAllocator);
if (result != VK_SUCCESS)
goto error_state;
anv_shader_heap_upload(&device->shader_heap,
shader->kernel,
shader_data->code,
reloc.relocated_code,
shader->prog_data,
shader->stats->dispatch_width);
anv_shader_reloc_end(&reloc);
if (mesa_shader_stage_is_rt(shader->vk.stage)) {
const struct brw_bs_prog_data *bs_prog_data =
(const struct brw_bs_prog_data *)shader->prog_data;
@ -879,16 +907,19 @@ anv_replay_rt_shader_group(struct vk_device *vk_device,
64, true, offset);
assert(shader->replay_kernel.alloc_size != 0);
/* TODO: make a copy of the code to leave it untouched */
VkResult result =
anv_shader_reloc(device, shader->code, shader, &vk_device->alloc);
struct anv_shader_reloc reloc;
VkResult result = anv_shader_reloc_begin(&reloc, device,
shader->code,
shader, NULL);
assert(result == VK_SUCCESS);
anv_shader_heap_upload(&device->shader_heap,
shader->replay_kernel,
shader->code,
reloc.relocated_code,
shader->prog_data,
shader->stats->dispatch_width);
anv_shader_reloc_end(&reloc);
}
simple_mtx_unlock(&shader->replay_mutex);