diff options
author | Christian König <christian.koenig@amd.com> | 2015-05-07 15:19:24 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-05-17 09:53:50 -0700 |
commit | 5f599720ae1435796054182a90622b64ab938038 (patch) | |
tree | 455198c8c7aa4ed4a7543468d7ffa6f6668376c6 /drivers/gpu/drm/radeon | |
parent | 0bccb94f33d85268b68698079794bb6e6f5de7df (diff) | |
download | lwn-5f599720ae1435796054182a90622b64ab938038.tar.gz lwn-5f599720ae1435796054182a90622b64ab938038.zip |
drm/radeon: more strictly validate the UVD codec
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>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_uvd.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 5e20c34e566d..bcfac7624550 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -350,6 +350,29 @@ static int radeon_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[]) 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[]) { @@ -392,7 +415,11 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, 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) { @@ -412,8 +439,10 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, 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; |