diff options
author | Jordan Crouse <jcrouse@codeaurora.org> | 2016-12-20 08:54:29 -0700 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2016-12-29 15:02:58 -0500 |
commit | 88b333b0ed790f9433ff542b163bf972953b74d3 (patch) | |
tree | b3edf10c51b3faf7b36eda931236a257022185ba /drivers/gpu/drm/msm/msm_ringbuffer.c | |
parent | 4a401ceeef7bf3bc55f5e913cbf19d6038cf83c6 (diff) | |
download | op-kernel-dev-88b333b0ed790f9433ff542b163bf972953b74d3.zip op-kernel-dev-88b333b0ed790f9433ff542b163bf972953b74d3.tar.gz |
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.c | 3 |
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 f326cf6..67b34e0 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) { |