Skip to content

Commit

Permalink
drm/vc4: Add support for branching in shader validation.
Browse files Browse the repository at this point in the history
We're already checking that branch instructions are between the start
of the shader and the proper PROG_END sequence.  The other thing we
need to make branching safe is to verify that the shader doesn't read
past the end of the uniforms stream.

To do that, we require that at any basic block reading uniforms have
the following instructions:

load_imm temp, <next offset within uniform stream>
add unif_addr, temp, unif

The instructions are generated by userspace, and the kernel verifies
that the load_imm is of the expected offset, and that the add adds it
to a uniform.  We track which uniform in the stream that is, and at
draw call time fix up the uniform stream to have the address of the
start of the shader's uniforms at that location.

Signed-off-by: Eric Anholt <[email protected]>
  • Loading branch information
anholt committed Jul 15, 2016
1 parent 93aa9ae commit 6d45c81
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 17 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/vc4/vc4_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,9 @@ struct vc4_validated_shader_info {
uint32_t uniforms_src_size;
uint32_t num_texture_samples;
struct vc4_texture_sample_info *texture_samples;

uint32_t num_uniform_addr_offsets;
uint32_t *uniform_addr_offsets;
};

/**
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/vc4/vc4_qpu_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ enum qpu_unpack_r4 {
#define QPU_OP_ADD_SHIFT 24
#define QPU_OP_ADD_MASK QPU_MASK(28, 24)

#define QPU_LOAD_IMM_SHIFT 0
#define QPU_LOAD_IMM_MASK QPU_MASK(31, 0)

#define QPU_BRANCH_TARGET_SHIFT 0
#define QPU_BRANCH_TARGET_MASK QPU_MASK(31, 0)

Expand Down
13 changes: 12 additions & 1 deletion drivers/gpu/drm/vc4/vc4_validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ validate_gl_shader_rec(struct drm_device *dev,
uint32_t src_offset = *(uint32_t *)(pkt_u + o);
uint32_t *texture_handles_u;
void *uniform_data_u;
uint32_t tex;
uint32_t tex, uni;

*(uint32_t *)(pkt_v + o) = bo[i]->paddr + src_offset;

Expand Down Expand Up @@ -840,6 +840,17 @@ validate_gl_shader_rec(struct drm_device *dev,
}
}

/* Fill in the uniform slots that need this shader's
* start-of-uniforms address (used for resetting the uniform
* stream in the presence of control flow).
*/
for (uni = 0;
uni < validated_shader->num_uniform_addr_offsets;
uni++) {
uint32_t o = validated_shader->uniform_addr_offsets[uni];
((uint32_t *)exec->uniforms_v)[o] = exec->uniforms_p;
}

*(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p;

exec->uniforms_u += validated_shader->uniforms_src_size;
Expand Down
Loading

0 comments on commit 6d45c81

Please sign in to comment.