diff options
author | Jean Delvare <khali@linux-fr.org> | 2010-05-11 00:01:45 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-05-11 00:01:48 -0400 |
commit | c9ff04c941d2cd87d27496d7fee8923238bb2ebb (patch) | |
tree | 42ed249578600f9c03653ec27bf1a70589dcb168 /drivers | |
parent | 8cfe92d683a0041ac8e016a0b0a487c99a78f6c1 (diff) |
drm/radeon: Fix 3 regressions - since buffer rework
Commit b4fe945405e477cded91772b4fec854705443dd5 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: Jean Delvare <khali@linux-fr.org>
Cc: Pauli Nieminen <suokkos@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_state.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 40ab6d9c3736..cc5316dcf580 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -424,7 +424,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * | |||
424 | if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && | 424 | if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && |
425 | (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | 425 | (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { |
426 | u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); | 426 | u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); |
427 | offset = *cmd << 10; | 427 | offset = *cmd3 << 10; |
428 | if (radeon_check_and_fixup_offset | 428 | if (radeon_check_and_fixup_offset |
429 | (dev_priv, file_priv, &offset)) { | 429 | (dev_priv, file_priv, &offset)) { |
430 | DRM_ERROR("Invalid second packet offset\n"); | 430 | DRM_ERROR("Invalid second packet offset\n"); |
@@ -2895,9 +2895,12 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, | |||
2895 | return rv; | 2895 | return rv; |
2896 | rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer, | 2896 | rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer, |
2897 | cmdbuf->bufsz); | 2897 | cmdbuf->bufsz); |
2898 | if (rv) | 2898 | if (rv) { |
2899 | drm_buffer_free(cmdbuf->buffer); | ||
2899 | return rv; | 2900 | return rv; |
2900 | } | 2901 | } |
2902 | } else | ||
2903 | goto done; | ||
2901 | 2904 | ||
2902 | orig_nbox = cmdbuf->nbox; | 2905 | orig_nbox = cmdbuf->nbox; |
2903 | 2906 | ||
@@ -2905,8 +2908,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, | |||
2905 | int temp; | 2908 | int temp; |
2906 | temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); | 2909 | temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); |
2907 | 2910 | ||
2908 | if (cmdbuf->bufsz != 0) | 2911 | drm_buffer_free(cmdbuf->buffer); |
2909 | drm_buffer_free(cmdbuf->buffer); | ||
2910 | 2912 | ||
2911 | return temp; | 2913 | return temp; |
2912 | } | 2914 | } |
@@ -3012,16 +3014,15 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, | |||
3012 | } | 3014 | } |
3013 | } | 3015 | } |
3014 | 3016 | ||
3015 | if (cmdbuf->bufsz != 0) | 3017 | drm_buffer_free(cmdbuf->buffer); |
3016 | drm_buffer_free(cmdbuf->buffer); | ||
3017 | 3018 | ||
3019 | done: | ||
3018 | DRM_DEBUG("DONE\n"); | 3020 | DRM_DEBUG("DONE\n"); |
3019 | COMMIT_RING(); | 3021 | COMMIT_RING(); |
3020 | return 0; | 3022 | return 0; |
3021 | 3023 | ||
3022 | err: | 3024 | err: |
3023 | if (cmdbuf->bufsz != 0) | 3025 | drm_buffer_free(cmdbuf->buffer); |
3024 | drm_buffer_free(cmdbuf->buffer); | ||
3025 | return -EINVAL; | 3026 | return -EINVAL; |
3026 | } | 3027 | } |
3027 | 3028 | ||