Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1704372

[PATCH 3.18 44/50] drm/msm: Ensure that the hardware write pointer is valid

From Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Newsgroups linux.kernel
Subject [PATCH 3.18 44/50] drm/msm: Ensure that the hardware write pointer is valid
Date 2017-08-05 01:40 +0200
Message-ID <uaUmh-5dC-65@gated-at.bofh.it> (permalink)
References <uaUcy-5a1-15@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


3.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jordan Crouse <jcrouse@codeaurora.org>


[ Upstream commit 88b333b0ed790f9433ff542b163bf972953b74d3 ]

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: Jordan Crouse <jcrouse@codeaurora.org>
[squash in is_power_of_2() check]
Signed-off-by: Rob Clark <robdclark@gmail.com>

Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c |    9 ++++++++-
 drivers/gpu/drm/msm/msm_ringbuffer.c    |    3 ++-
 2 files changed, 10 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -199,7 +199,14 @@ void adreno_flush(struct msm_gpu *gpu)
 void adreno_idle(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);
 
 	/* wait for CP to drain ringbuffer: */
 	if (spin_until(adreno_gpu->memptrs->rptr == wptr))
--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -23,7 +23,8 @@ struct msm_ringbuffer *msm_ringbuffer_ne
 	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) {

Back to linux.kernel | Previous | Next | Find similar | Unroll thread


Thread

[PATCH 3.18 44/50] drm/msm: Ensure that the hardware write pointer is valid Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-08-05 01:40 +0200

csiph-web