Messages in this thread - First message in thread
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
- "Levin, Alexander (Sasha Levin)"
Patch in this message | | | From | "Levin, Alexander (Sasha Levin)" <> | Subject | [PATCH for v4.9 LTS 13/87] drm/msm: Ensure that the hardware write pointer is valid | Date | Sat, 15 Jul 2017 01:26:01 +0000 |
| |
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> --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 9 ++++++++- drivers/gpu/drm/msm/msm_ringbuffer.c | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f386f463278d..a904082ed206 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -210,7 +210,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(); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index f326cf6a32e6..67b34e069abf 100644 --- 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_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) { -- 2.11.0
| |