diff options
author | Christian König <christian.koenig@amd.com> | 2015-05-07 09:19:24 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-05-07 11:00:17 -0400 |
commit | d52cdfa4a0c6406bbfb33206341eaf1fb1555994 (patch) | |
tree | ba4d4c2bbc8323d182890e49783b25e8c483e8e9 /drivers/gpu | |
parent | a1b403da70e038ca6c6c6fe434d1d873546873a3 (diff) |
drm/radeon: more strictly validate the UVD codec
MPEG 2/4 are only supported since UVD3.
Signed-off-by: Christian König <christian.koenig@amd.com>
CC: stable@vger.kernel.org
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-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 f67a6aae0010..cd630287cf0a 100644 --- 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(uint32_t *msg, unsigned buf_sizes[]) | |||
396 | return 0; | 396 | return 0; |
397 | } | 397 | } |
398 | 398 | ||
399 | static int radeon_uvd_validate_codec(struct radeon_cs_parser *p, | ||
400 | unsigned stream_type) | ||
401 | { | ||
402 | switch (stream_type) { | ||
403 | case 0: /* H264 */ | ||
404 | case 1: /* VC1 */ | ||
405 | /* always supported */ | ||
406 | return 0; | ||
407 | |||
408 | case 3: /* MPEG2 */ | ||
409 | case 4: /* MPEG4 */ | ||
410 | /* only since UVD 3 */ | ||
411 | if (p->rdev->family >= CHIP_PALM) | ||
412 | return 0; | ||
413 | |||
414 | /* fall through */ | ||
415 | default: | ||
416 | DRM_ERROR("UVD codec not supported by hardware %d!\n", | ||
417 | stream_type); | ||
418 | return -EINVAL; | ||
419 | } | ||
420 | } | ||
421 | |||
399 | static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | 422 | static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, |
400 | unsigned offset, unsigned buf_sizes[]) | 423 | unsigned offset, unsigned buf_sizes[]) |
401 | { | 424 | { |
@@ -440,7 +463,11 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
440 | case 0: | 463 | case 0: |
441 | /* it's a create msg, calc image size (width * height) */ | 464 | /* it's a create msg, calc image size (width * height) */ |
442 | img_size = msg[7] * msg[8]; | 465 | img_size = msg[7] * msg[8]; |
466 | |||
467 | r = radeon_uvd_validate_codec(p, msg[4]); | ||
443 | radeon_bo_kunmap(bo); | 468 | radeon_bo_kunmap(bo); |
469 | if (r) | ||
470 | return r; | ||
444 | 471 | ||
445 | /* try to alloc a new handle */ | 472 | /* try to alloc a new handle */ |
446 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | 473 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
@@ -460,8 +487,10 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
460 | return -EINVAL; | 487 | return -EINVAL; |
461 | 488 | ||
462 | case 1: | 489 | case 1: |
463 | /* it's a decode msg, calc buffer sizes */ | 490 | /* it's a decode msg, validate codec and calc buffer sizes */ |
464 | r = radeon_uvd_cs_msg_decode(msg, buf_sizes); | 491 | r = radeon_uvd_validate_codec(p, msg[4]); |
492 | if (!r) | ||
493 | r = radeon_uvd_cs_msg_decode(msg, buf_sizes); | ||
465 | radeon_bo_kunmap(bo); | 494 | radeon_bo_kunmap(bo); |
466 | if (r) | 495 | if (r) |
467 | return r; | 496 | return r; |