summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/msm_ringbuffer.c
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2016-12-20 16:54:29 +0100
committerRob Clark <robdclark@gmail.com>2016-12-29 21:02:58 +0100
commit88b333b0ed790f9433ff542b163bf972953b74d3 (patch)
treeb3edf10c51b3faf7b36eda931236a257022185ba /drivers/gpu/drm/msm/msm_ringbuffer.c
parentMerge tag 'drm-intel-next-fixes-2016-12-22' of git://anongit.freedesktop.org/... (diff)
downloadlinux-88b333b0ed790f9433ff542b163bf972953b74d3.tar.xz
linux-88b333b0ed790f9433ff542b163bf972953b74d3.zip
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: Jordan Crouse <jcrouse@codeaurora.org> [squash in is_power_of_2() check] Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c3
1 files changed, 2 insertions, 1 deletions
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) {