aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/vc4/vc4_simulator.c7
-rw-r--r--src/gallium/drivers/vc4/vc4_simulator_validate.c89
-rw-r--r--src/gallium/drivers/vc4/vc4_simulator_validate.h22
3 files changed, 81 insertions, 37 deletions
diff --git a/src/gallium/drivers/vc4/vc4_simulator.c b/src/gallium/drivers/vc4/vc4_simulator.c
index b2f2b669dc9..88eda4fe722 100644
--- a/src/gallium/drivers/vc4/vc4_simulator.c
+++ b/src/gallium/drivers/vc4/vc4_simulator.c
@@ -70,16 +70,15 @@ vc4_simulator_pin_bos(struct drm_device *dev, struct exec_info *exec)
struct vc4_bo **bos = vc4->bo_pointers.base;
exec->bo_count = args->bo_handle_count;
- exec->bo = calloc(exec->bo_count, sizeof(void *));
+ exec->bo = calloc(exec->bo_count, sizeof(struct vc4_bo_exec_state));
for (int i = 0; i < exec->bo_count; i++) {
struct vc4_bo *bo = bos[i];
struct drm_gem_cma_object *obj = vc4_wrap_bo_with_cma(dev, bo);
memcpy(obj->vaddr, bo->map, bo->size);
- exec->bo[i] = obj;
+ exec->bo[i].bo = obj;
}
-
return 0;
}
@@ -87,7 +86,7 @@ static int
vc4_simulator_unpin_bos(struct exec_info *exec)
{
for (int i = 0; i < exec->bo_count; i++) {
- struct drm_gem_cma_object *obj = exec->bo[i];
+ struct drm_gem_cma_object *obj = exec->bo[i].bo;
struct vc4_bo *bo = obj->bo;
memcpy(bo->map, obj->vaddr, bo->size);
diff --git a/src/gallium/drivers/vc4/vc4_simulator_validate.c b/src/gallium/drivers/vc4/vc4_simulator_validate.c
index fafb45fa8fd..3db74a0b18b 100644
--- a/src/gallium/drivers/vc4/vc4_simulator_validate.c
+++ b/src/gallium/drivers/vc4/vc4_simulator_validate.c
@@ -47,6 +47,44 @@
void *validated, \
void *untrusted
+static bool
+vc4_use_bo(struct exec_info *exec,
+ uint32_t hindex,
+ enum vc4_bo_mode mode,
+ struct drm_gem_cma_object **obj)
+{
+ *obj = NULL;
+
+ if (hindex >= exec->bo_count) {
+ DRM_ERROR("BO index %d greater than BO count %d\n",
+ hindex, exec->bo_count);
+ return false;
+ }
+
+ if (exec->bo[hindex].mode != mode) {
+ if (exec->bo[hindex].mode == VC4_MODE_UNDECIDED) {
+ exec->bo[hindex].mode = mode;
+ } else {
+ DRM_ERROR("BO index %d reused with mode %d vs %d\n",
+ hindex, exec->bo[hindex].mode, mode);
+ return false;
+ }
+ }
+
+ *obj = exec->bo[hindex].bo;
+ return true;
+}
+
+static bool
+vc4_use_handle(struct exec_info *exec,
+ uint32_t gem_handles_packet_index,
+ enum vc4_bo_mode mode,
+ struct drm_gem_cma_object **obj)
+{
+ return vc4_use_bo(exec, exec->bo_index[gem_handles_packet_index],
+ mode, obj);
+}
+
static uint32_t
gl_shader_rec_size(uint32_t pointer_bits)
{
@@ -66,7 +104,8 @@ validate_branch_to_sublist(VALIDATE_ARGS)
/* XXX: Validate address jumped to */
- target = exec->bo[exec->bo_index[0]];
+ if (!vc4_use_handle(exec, 0, VC4_MODE_TILE_ALLOC, &target))
+ return -EINVAL;
*(uint32_t *)(validated + 0) =
*(uint32_t *)(untrusted + 0) + target->paddr;
@@ -78,11 +117,14 @@ static int
validate_loadstore_tile_buffer_general(VALIDATE_ARGS)
{
uint32_t packet_b0 = *(uint8_t *)(untrusted + 0);
- struct drm_gem_cma_object *fbo = exec->bo[exec->bo_index[0]];
+ struct drm_gem_cma_object *fbo;
if ((packet_b0 & 0xf) == VC4_LOADSTORE_TILE_BUFFER_NONE)
return 0;
+ if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &fbo))
+ return -EINVAL;
+
/* XXX: Validate address offset */
*(uint32_t *)(validated + 2) =
*(uint32_t *)(untrusted + 2) + fbo->paddr;
@@ -109,7 +151,9 @@ validate_indexed_prim_list(VALIDATE_ARGS)
return -EINVAL;
}
- ib = exec->bo[exec->bo_index[0]];
+
+ if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &ib))
+ return -EINVAL;
if (ib_access_end > ib->base.size) {
DRM_ERROR("IB access out of bounds (%d/%d)\n",
ib_access_end, ib->base.size);
@@ -180,8 +224,9 @@ validate_tile_binning_config(VALIDATE_ARGS)
struct drm_gem_cma_object *tile_allocation;
struct drm_gem_cma_object *tile_state_data_array;
- tile_allocation = exec->bo[exec->bo_index[0]];
- tile_state_data_array = exec->bo[exec->bo_index[1]];
+ 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 =
@@ -198,7 +243,8 @@ validate_tile_rendering_mode_config(VALIDATE_ARGS)
{
struct drm_gem_cma_object *fbo;
- fbo = exec->bo[exec->bo_index[0]];
+ if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &fbo))
+ return -EINVAL;
/* XXX: Validate offsets */
*(uint32_t *)validated =
@@ -210,18 +256,7 @@ validate_tile_rendering_mode_config(VALIDATE_ARGS)
static int
validate_gem_handles(VALIDATE_ARGS)
{
- int i;
-
memcpy(exec->bo_index, untrusted, sizeof(exec->bo_index));
-
- for (i = 0; i < ARRAY_SIZE(exec->bo_index); i++) {
- if (exec->bo_index[i] >= exec->bo_count) {
- DRM_ERROR("Validated BO index %d >= %d\n",
- exec->bo_index[i], exec->bo_count);
- return -EINVAL;
- }
- }
-
return 0;
}
@@ -379,12 +414,8 @@ reloc_tex(struct exec_info *exec,
sample->p_offset[0]);
uint32_t *validated_p0 = exec->uniforms_v + sample->p_offset[0];
- if (texture_handle_index >= exec->bo_count) {
- DRM_ERROR("texture handle index %d >= %d\n",
- texture_handle_index, exec->bo_count);
+ if (!vc4_use_bo(exec, texture_handle_index, VC4_MODE_RENDER, &tex))
return false;
- }
- tex = exec->bo[texture_handle_index];
*validated_p0 = tex->paddr + unvalidated_p0;
@@ -467,12 +498,16 @@ validate_shader_rec(struct drm_device *dev,
exec->shader_rec_size -= packet_size;
for (i = 0; i < nr_relocs; i++) {
- if (src_handles[i] >= exec->bo_count) {
- DRM_ERROR("shader rec bo index %d > %d\n",
- src_handles[i], exec->bo_count);
- return -EINVAL;
+ enum vc4_bo_mode mode;
+
+ if (i < nr_fixed_relocs && relocs[i].type == RELOC_CODE)
+ mode = VC4_MODE_SHADER;
+ else
+ mode = VC4_MODE_RENDER;
+
+ if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) {
+ return false;
}
- bo[i] = exec->bo[src_handles[i]];
}
for (i = 0; i < nr_fixed_relocs; i++) {
diff --git a/src/gallium/drivers/vc4/vc4_simulator_validate.h b/src/gallium/drivers/vc4/vc4_simulator_validate.h
index 52f664adbc1..1f3d23f881e 100644
--- a/src/gallium/drivers/vc4/vc4_simulator_validate.h
+++ b/src/gallium/drivers/vc4/vc4_simulator_validate.h
@@ -69,6 +69,19 @@ struct drm_gem_cma_object {
void *vaddr;
};
+enum vc4_bo_mode {
+ VC4_MODE_UNDECIDED,
+ VC4_MODE_TILE_ALLOC,
+ VC4_MODE_TSDA,
+ VC4_MODE_RENDER,
+ VC4_MODE_SHADER,
+};
+
+struct vc4_bo_exec_state {
+ struct drm_gem_cma_object *bo;
+ enum vc4_bo_mode mode;
+};
+
struct exec_info {
/* Kernel-space copy of the ioctl arguments */
struct drm_vc4_submit_cl *args;
@@ -76,14 +89,11 @@ struct exec_info {
/* This is the array of BOs that were looked up at the start of exec.
* Command validation will use indices into this array.
*/
- struct drm_gem_cma_object **bo;
+ struct vc4_bo_exec_state *bo;
uint32_t bo_count;
- /* Current indices into @bo loaded by the non-hardware packet
- * that passes in indices. This can be used even without
- * checking that we've seen one of those packets, because
- * @bo_count is always >= 1, and this struct is initialized to
- * 0.
+ /* Current unvalidated indices into @bo loaded by the non-hardware
+ * VC4_PACKET_GEM_HANDLES.
*/
uint32_t bo_index[2];
uint32_t max_width, max_height;