v3dv: ensure at least V3D_CL_MAX_INSTR_SIZE bytes in last CL instruction

The CLE parser in the sim will read this many bytes for each instruction
in a CL, so we should ensure we have at least that many bytes available
in the BO when reading the last instruction, otherwise we can trigger
a GMP violation. It is not clear whether this behavior applies to real
hardware too.

cc: mesa-stable

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21162>
This commit is contained in:
Iago Toral Quiroga
2023-02-06 13:16:12 +01:00
parent 079247e046
commit c2601f0690
2 changed files with 13 additions and 7 deletions

View File

@@ -24,6 +24,8 @@
#ifndef V3D_LIMITS_H #ifndef V3D_LIMITS_H
#define V3D_LIMITS_H #define V3D_LIMITS_H
#define V3D_CL_MAX_INSTR_SIZE 25
/* Number of channels a QPU thread executes in parallel. Also known as /* Number of channels a QPU thread executes in parallel. Also known as
* gl_SubGroupSizeARB. * gl_SubGroupSizeARB.
*/ */

View File

@@ -122,14 +122,18 @@ v3dv_cl_ensure_space_with_branch(struct v3dv_cl *cl, uint32_t space)
* end with a 'return from sub list' command. * end with a 'return from sub list' command.
*/ */
bool needs_return_from_sub_list = false; bool needs_return_from_sub_list = false;
if (cl->job->type == V3DV_JOB_TYPE_GPU_CL_SECONDARY) { if (cl->job->type == V3DV_JOB_TYPE_GPU_CL_SECONDARY && cl->size > 0)
if (cl->size > 0) {
needs_return_from_sub_list = true; needs_return_from_sub_list = true;
space += cl_packet_length(RETURN_FROM_SUB_LIST);
} /*
} else { * The CLE processor in the simulator tries to read V3D_CL_MAX_INSTR_SIZE
space += cl_packet_length(BRANCH); * bytes form the CL for each new instruction. If the last instruction in our
} * CL is smaller than that, and there are not at least V3D_CL_MAX_INSTR_SIZE
* bytes until the end of the BO, it will read out of bounds and possibly
* cause a GMP violation interrupt to trigger. Ensure we always have at
* least that many bytes available to read with the last instruction.
*/
space += V3D_CL_MAX_INSTR_SIZE;
if (v3dv_cl_offset(cl) + space <= cl->size) if (v3dv_cl_offset(cl) + space <= cl->size)
return; return;