| From d52cdfa4a0c6406bbfb33206341eaf1fb1555994 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> |
| Date: Thu, 7 May 2015 15:19:24 +0200 |
| Subject: drm/radeon: more strictly validate the UVD codec |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> |
| |
| commit d52cdfa4a0c6406bbfb33206341eaf1fb1555994 upstream. |
| |
| MPEG 2/4 are only supported since UVD3. |
| |
| Signed-off-by: Christian Kรถnig <christian.koenig@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/radeon/radeon_uvd.c | 33 +++++++++++++++++++++++++++++++-- |
| 1 file changed, 31 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/gpu/drm/radeon/radeon_uvd.c |
| +++ b/drivers/gpu/drm/radeon/radeon_uvd.c |
| @@ -396,6 +396,29 @@ static int radeon_uvd_cs_msg_decode(uint |
| return 0; |
| } |
| |
| +static int radeon_uvd_validate_codec(struct radeon_cs_parser *p, |
| + unsigned stream_type) |
| +{ |
| + switch (stream_type) { |
| + case 0: /* H264 */ |
| + case 1: /* VC1 */ |
| + /* always supported */ |
| + return 0; |
| + |
| + case 3: /* MPEG2 */ |
| + case 4: /* MPEG4 */ |
| + /* only since UVD 3 */ |
| + if (p->rdev->family >= CHIP_PALM) |
| + return 0; |
| + |
| + /* fall through */ |
| + default: |
| + DRM_ERROR("UVD codec not supported by hardware %d!\n", |
| + stream_type); |
| + return -EINVAL; |
| + } |
| +} |
| + |
| static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, |
| unsigned offset, unsigned buf_sizes[]) |
| { |
| @@ -440,7 +463,11 @@ static int radeon_uvd_cs_msg(struct rade |
| case 0: |
| /* it's a create msg, calc image size (width * height) */ |
| img_size = msg[7] * msg[8]; |
| + |
| + r = radeon_uvd_validate_codec(p, msg[4]); |
| radeon_bo_kunmap(bo); |
| + if (r) |
| + return r; |
| |
| /* try to alloc a new handle */ |
| for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
| @@ -460,8 +487,10 @@ static int radeon_uvd_cs_msg(struct rade |
| return -EINVAL; |
| |
| case 1: |
| - /* it's a decode msg, calc buffer sizes */ |
| - r = radeon_uvd_cs_msg_decode(msg, buf_sizes); |
| + /* it's a decode msg, validate codec and calc buffer sizes */ |
| + r = radeon_uvd_validate_codec(p, msg[4]); |
| + if (!r) |
| + r = radeon_uvd_cs_msg_decode(msg, buf_sizes); |
| radeon_bo_kunmap(bo); |
| if (r) |
| return r; |