Commit c9ff04c9 authored by Jean Delvare's avatar Jean Delvare Committed by Dave Airlie

drm/radeon: Fix 3 regressions - since buffer rework

Commit b4fe9454 introduced 3 bugs,
fix them:

* Use the right command dword for second packet offset in
  RADEON_CNTL_PAINT/BITBLT_MULTI.
* Don't leak memory if drm_buffer_copy_from_user() fails.
* Don't call drm_buffer_unprocessed() unless drm_buffer_alloc() and
  drm_buffer_copy_from_user() have been called successfully first.
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
Cc: Pauli Nieminen <suokkos@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 8cfe92d6
...@@ -424,7 +424,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * ...@@ -424,7 +424,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
(*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3);
offset = *cmd << 10; offset = *cmd3 << 10;
if (radeon_check_and_fixup_offset if (radeon_check_and_fixup_offset
(dev_priv, file_priv, &offset)) { (dev_priv, file_priv, &offset)) {
DRM_ERROR("Invalid second packet offset\n"); DRM_ERROR("Invalid second packet offset\n");
...@@ -2895,9 +2895,12 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, ...@@ -2895,9 +2895,12 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
return rv; return rv;
rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer, rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer,
cmdbuf->bufsz); cmdbuf->bufsz);
if (rv) if (rv) {
drm_buffer_free(cmdbuf->buffer);
return rv; return rv;
} }
} else
goto done;
orig_nbox = cmdbuf->nbox; orig_nbox = cmdbuf->nbox;
...@@ -2905,7 +2908,6 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, ...@@ -2905,7 +2908,6 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
int temp; int temp;
temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
if (cmdbuf->bufsz != 0)
drm_buffer_free(cmdbuf->buffer); drm_buffer_free(cmdbuf->buffer);
return temp; return temp;
...@@ -3012,15 +3014,14 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, ...@@ -3012,15 +3014,14 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
} }
} }
if (cmdbuf->bufsz != 0)
drm_buffer_free(cmdbuf->buffer); drm_buffer_free(cmdbuf->buffer);
done:
DRM_DEBUG("DONE\n"); DRM_DEBUG("DONE\n");
COMMIT_RING(); COMMIT_RING();
return 0; return 0;
err: err:
if (cmdbuf->bufsz != 0)
drm_buffer_free(cmdbuf->buffer); drm_buffer_free(cmdbuf->buffer);
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment