diff options
author | Iago Toral Quiroga <[email protected]> | 2019-11-26 15:28:52 +0100 |
---|---|---|
committer | Iago Toral Quiroga <[email protected]> | 2019-11-27 08:43:13 +0100 |
commit | 18a09e788d8d0e122263159cb6cb1c70d243b02d (patch) | |
tree | 2226508c05a30b6a0e92c568817b89b6d5ab1636 /src/gallium/drivers | |
parent | a24f1c8f7f093d98a8856e47bb190a1016457414 (diff) |
v3d: fix indirect BO allocation for uniforms
We were always ensuring a minimum size of 4 bytes for uniforms
for the case where we don't have any, to account for hardware pre-fetching
of the uniform stream, however, pre-fetching could also lead to to out
of bounds reads when have read the last uniform in the stream, so we
probably want to have the extra 4 bytes to prevent the kernel from
observing invalid memory accesses when the uniform stream sits right at
the end of a page.
This seems to fix MMU exceptions reported with a Linux 5.4 kernel.
Credit goes to Phil Elwell for identifying the problem and narrowing
it down to memory accesses in the uniform stream.
Reported-by: Phil Elwell <[email protected]>
Tested-by: Phil Elwell <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/v3d/v3d_uniforms.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/gallium/drivers/v3d/v3d_uniforms.c b/src/gallium/drivers/v3d/v3d_uniforms.c index 897987e5b60..a5b98925c60 100644 --- a/src/gallium/drivers/v3d/v3d_uniforms.c +++ b/src/gallium/drivers/v3d/v3d_uniforms.c @@ -215,10 +215,15 @@ v3d_write_uniforms(struct v3d_context *v3d, struct v3d_job *job, struct v3d_uniform_list *uinfo = &shader->prog_data.base->uniforms; const uint32_t *gallium_uniforms = cb->cb[0].user_buffer; - /* We always need to return some space for uniforms, because the HW - * will be prefetching, even if we don't read any in the program. + /* The hardware always pre-fetches the next uniform (also when there + * aren't any), so we always allocate space for an extra slot. This + * fixes MMU exceptions reported since Linux kernel 5.4 when the + * uniforms fill up the tail bytes of a page in the indirect + * BO. In that scenario, when the hardware pre-fetches after reading + * the last uniform it will read beyond the end of the page and trigger + * the MMU exception. */ - v3d_cl_ensure_space(&job->indirect, MAX2(uinfo->count, 1) * 4, 4); + v3d_cl_ensure_space(&job->indirect, (uinfo->count + 1) * 4, 4); struct v3d_cl_reloc uniform_stream = cl_get_address(&job->indirect); v3d_bo_reference(uniform_stream.bo); |