vc4: Add a bunch of validation of the binning mode config.
This commit is contained in:
parent
b6caa9556c
commit
0bc2aed90f
|
@ -97,18 +97,47 @@ gl_shader_rec_size(uint32_t pointer_bits)
|
|||
return 36 + attribute_count * (extended ? 12 : 8);
|
||||
}
|
||||
|
||||
static int
|
||||
validate_start_tile_binning(VALIDATE_ARGS)
|
||||
{
|
||||
if (exec->found_start_tile_binning_packet) {
|
||||
DRM_ERROR("Duplicate VC4_PACKET_START_TILE_BINNING\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
exec->found_start_tile_binning_packet = true;
|
||||
|
||||
if (!exec->found_tile_binning_mode_config_packet) {
|
||||
DRM_ERROR("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
validate_branch_to_sublist(VALIDATE_ARGS)
|
||||
{
|
||||
struct drm_gem_cma_object *target;
|
||||
|
||||
/* XXX: Validate address jumped to */
|
||||
uint32_t offset;
|
||||
|
||||
if (!vc4_use_handle(exec, 0, VC4_MODE_TILE_ALLOC, &target))
|
||||
return -EINVAL;
|
||||
|
||||
*(uint32_t *)(validated + 0) =
|
||||
*(uint32_t *)(untrusted + 0) + target->paddr;
|
||||
if (target != exec->tile_alloc_bo) {
|
||||
DRM_ERROR("Juimping to BOs other than tile alloc unsupported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
offset = *(uint32_t *)(untrusted + 0);
|
||||
if (offset % exec->tile_alloc_init_block_size ||
|
||||
offset / exec->tile_alloc_init_block_size >
|
||||
exec->bin_tiles_x * exec->bin_tiles_y) {
|
||||
DRM_ERROR("VC4_PACKET_BRANCH_TO_SUB_LIST must jump to initial "
|
||||
"tile allocation space.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*(uint32_t *)(validated + 0) = target->paddr + offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -223,17 +252,79 @@ validate_tile_binning_config(VALIDATE_ARGS)
|
|||
{
|
||||
struct drm_gem_cma_object *tile_allocation;
|
||||
struct drm_gem_cma_object *tile_state_data_array;
|
||||
uint8_t flags;
|
||||
uint32_t tile_allocation_size;
|
||||
|
||||
if (!vc4_use_handle(exec, 0, VC4_MODE_TILE_ALLOC, &tile_allocation) ||
|
||||
!vc4_use_handle(exec, 1, VC4_MODE_TSDA, &tile_state_data_array))
|
||||
return -EINVAL;
|
||||
|
||||
/* XXX: Validate offsets */
|
||||
*(uint32_t *)validated =
|
||||
*(uint32_t *)untrusted + tile_allocation->paddr;
|
||||
if (exec->found_tile_binning_mode_config_packet) {
|
||||
DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
exec->found_tile_binning_mode_config_packet = true;
|
||||
|
||||
*(uint32_t *)(validated + 8) =
|
||||
*(uint32_t *)(untrusted + 8) + tile_state_data_array->paddr;
|
||||
exec->bin_tiles_x = *(uint8_t *)(untrusted + 12);
|
||||
exec->bin_tiles_y = *(uint8_t *)(untrusted + 13);
|
||||
flags = *(uint8_t *)(untrusted + 14);
|
||||
|
||||
if (exec->bin_tiles_x == 0 ||
|
||||
exec->bin_tiles_y == 0) {
|
||||
DRM_ERROR("Tile binning config of %dx%d too small\n",
|
||||
exec->bin_tiles_x, exec->bin_tiles_y);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Our validation relies on the user not getting to set up their own
|
||||
* tile state/tile allocation BO contents.
|
||||
*/
|
||||
if (!(flags & VC4_BIN_CONFIG_AUTO_INIT_TSDA)) {
|
||||
DRM_ERROR("binning config missing "
|
||||
"VC4_BIN_CONFIG_AUTO_INIT_TSDA\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (flags & (VC4_BIN_CONFIG_DB_NON_MS |
|
||||
VC4_BIN_CONFIG_TILE_BUFFER_64BIT |
|
||||
VC4_BIN_CONFIG_MS_MODE_4X)) {
|
||||
DRM_ERROR("unsupported bining config flags 0x%02x\n", flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*(uint32_t *)(untrusted + 0) != 0) {
|
||||
DRM_ERROR("tile allocation offset != 0 unsupported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
tile_allocation_size = *(uint32_t *)(untrusted + 4);
|
||||
if (tile_allocation_size > tile_allocation->base.size) {
|
||||
DRM_ERROR("tile allocation size %d > BO size %d",
|
||||
tile_allocation_size, tile_allocation->base.size);
|
||||
return -EINVAL;
|
||||
}
|
||||
*(uint32_t *)validated = tile_allocation->paddr;
|
||||
exec->tile_alloc_bo = tile_allocation;
|
||||
|
||||
exec->tile_alloc_init_block_size = 1 << (5 + ((flags >> 5) & 3));
|
||||
if (exec->bin_tiles_x * exec->bin_tiles_y *
|
||||
exec->tile_alloc_init_block_size > tile_allocation_size) {
|
||||
DRM_ERROR("tile init exceeds tile alloc size (%d vs %d)\n",
|
||||
exec->bin_tiles_x * exec->bin_tiles_y *
|
||||
exec->tile_alloc_init_block_size,
|
||||
tile_allocation_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (*(uint32_t *)(untrusted + 8) != 0) {
|
||||
DRM_ERROR("TSDA offset != 0 unsupported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (exec->bin_tiles_x * exec->bin_tiles_y * 48 >
|
||||
tile_state_data_array->base.size) {
|
||||
DRM_ERROR("TSDA of %db too small for %dx%d bin config\n",
|
||||
tile_state_data_array->base.size,
|
||||
exec->bin_tiles_x, exec->bin_tiles_y);
|
||||
}
|
||||
*(uint32_t *)(validated + 8) = tile_state_data_array->paddr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -253,6 +344,25 @@ validate_tile_rendering_mode_config(VALIDATE_ARGS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
validate_tile_coordinates(VALIDATE_ARGS)
|
||||
{
|
||||
uint8_t tile_x = *(uint8_t *)(untrusted + 0);
|
||||
uint8_t tile_y = *(uint8_t *)(untrusted + 1);
|
||||
|
||||
if (tile_x >= exec->bin_tiles_x ||
|
||||
tile_y >= exec->bin_tiles_y) {
|
||||
DRM_ERROR("Tile coordinates %d,%d > bin config %d,%d\n",
|
||||
tile_x,
|
||||
tile_y,
|
||||
exec->bin_tiles_x,
|
||||
exec->bin_tiles_y);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
validate_gem_handles(VALIDATE_ARGS)
|
||||
{
|
||||
|
@ -271,10 +381,14 @@ static const struct cmd_info {
|
|||
[VC4_PACKET_NOP] = { 1, 1, 1, "nop", NULL },
|
||||
[VC4_PACKET_FLUSH] = { 1, 1, 1, "flush", NULL },
|
||||
[VC4_PACKET_FLUSH_ALL] = { 1, 0, 1, "flush all state", NULL },
|
||||
[VC4_PACKET_START_TILE_BINNING] = { 1, 0, 1, "start tile binning", NULL },
|
||||
[VC4_PACKET_START_TILE_BINNING] = { 1, 0, 1, "start tile binning", validate_start_tile_binning },
|
||||
[VC4_PACKET_INCREMENT_SEMAPHORE] = { 1, 0, 1, "increment semaphore", NULL },
|
||||
[VC4_PACKET_WAIT_ON_SEMAPHORE] = { 1, 1, 1, "wait on semaphore", NULL },
|
||||
[VC4_PACKET_BRANCH_TO_SUB_LIST] = { 1, 1, 5, "branch to sublist", validate_branch_to_sublist },
|
||||
/* BRANCH_TO_SUB_LIST is actually supported in the binner as well, but
|
||||
* we only use it from the render CL in order to jump into the tile
|
||||
* allocation BO.
|
||||
*/
|
||||
[VC4_PACKET_BRANCH_TO_SUB_LIST] = { 0, 1, 5, "branch to sublist", validate_branch_to_sublist },
|
||||
[VC4_PACKET_STORE_MS_TILE_BUFFER] = { 0, 1, 1, "store MS resolved tile color buffer", NULL },
|
||||
[VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF] = { 0, 1, 1, "store MS resolved tile color buffer and EOF", NULL },
|
||||
|
||||
|
@ -313,10 +427,7 @@ static const struct cmd_info {
|
|||
|
||||
[VC4_PACKET_CLEAR_COLORS] = { 0, 1, 14, "Clear Colors", NULL },
|
||||
|
||||
/* XXX: Do we need to validate here? It's got tile x/y number for
|
||||
* rendering
|
||||
*/
|
||||
[VC4_PACKET_TILE_COORDINATES] = { 0, 1, 3, "Tile Coordinates", NULL },
|
||||
[VC4_PACKET_TILE_COORDINATES] = { 0, 1, 3, "Tile Coordinates", validate_tile_coordinates },
|
||||
|
||||
[VC4_PACKET_GEM_HANDLES] = { 1, 1, 9, "GEM handles", validate_gem_handles },
|
||||
};
|
||||
|
@ -394,10 +505,16 @@ vc4_validate_cl(struct drm_device *dev,
|
|||
break;
|
||||
}
|
||||
|
||||
if (is_bin)
|
||||
if (is_bin) {
|
||||
exec->ct0ea = exec->ct0ca + dst_offset;
|
||||
else
|
||||
|
||||
if (!exec->found_start_tile_binning_packet) {
|
||||
DRM_ERROR("Bin CL missing VC4_PACKET_START_TILE_BINNING\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
exec->ct1ea = exec->ct1ca + dst_offset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -119,6 +119,12 @@ struct exec_info {
|
|||
/** How many shader state records the validator has seen. */
|
||||
uint32_t shader_state_count;
|
||||
|
||||
bool found_tile_binning_mode_config_packet;
|
||||
bool found_start_tile_binning_packet;
|
||||
uint8_t bin_tiles_x, bin_tiles_y;
|
||||
uint32_t tile_alloc_init_block_size;
|
||||
struct drm_gem_cma_object *tile_alloc_bo;
|
||||
|
||||
/**
|
||||
* Computed addresses pointing into exec_bo where we start the
|
||||
* bin thread (ct0) and render thread (ct1).
|
||||
|
|
Loading…
Reference in New Issue