drm/radeon: more strictly validate the UVD codec
authorChristian König <christian.koenig@amd.com>
Thu, 7 May 2015 13:19:24 +0000 (15:19 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 7 May 2015 15:00:17 +0000 (11:00 -0400)
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>
drivers/gpu/drm/radeon/radeon_uvd.c

index f67a6aae00100e1618985b1eac1b26e4643720c5..cd630287cf0a33fb404d36000f27630a40872e72 100644 (file)
@@ -396,6 +396,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[])
 {
@@ -440,7 +463,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) {
@@ -460,8 +487,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;