Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88b333b0 authored by Jordan Crouse's avatar Jordan Crouse Committed by Rob Clark
Browse files

drm/msm: Ensure that the hardware write pointer is valid



Currently the value written to CP_RB_WPTR is calculated on the fly as
(rb->next - rb->start). But as the code is designed rb->next is wrapped
before writing the commands so if a series of commands happened to
fit perfectly in the ringbuffer, rb->next would end up being equal to
rb->size / 4 and thus result in an out of bounds address to CP_RB_WPTR.

The easiest way to fix this is to mask WPTR when writing it to the
hardware; it makes the hardware happy and the rest of the ringbuffer
math appears to work and there isn't any point in upsetting anything.

Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
[squash in is_power_of_2() check]
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 4a401cee
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -213,7 +213,14 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
void adreno_flush(struct msm_gpu *gpu)
{
	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
	uint32_t wptr = get_wptr(gpu->rb);
	uint32_t wptr;

	/*
	 * Mask wptr value that we calculate to fit in the HW range. This is
	 * to account for the possibility that the last command fit exactly into
	 * the ringbuffer and rb->next hasn't wrapped to zero yet
	 */
	wptr = get_wptr(gpu->rb) & ((gpu->rb->size / 4) - 1);

	/* ensure writes to ringbuffer have hit system memory: */
	mb();
+2 −1
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size)
	struct msm_ringbuffer *ring;
	int ret;

	size = ALIGN(size, 4);   /* size should be dword aligned */
	if (WARN_ON(!is_power_of_2(size)))
		return ERR_PTR(-EINVAL);

	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
	if (!ring) {