]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
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)
committerLuis Henriques <luis.henriques@canonical.com>
Wed, 20 May 2015 12:26:11 +0000 (13:26 +0100)
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: Luis Henriques <luis.henriques@canonical.com>
drivers/gpu/drm/radeon/radeon_uvd.c

index 6463e05aeabd6275969b63d13907328da0117b3c..a86cc490c35f15618d04ebb146a541b5168ed87d 100644 (file)
@@ -351,6 +351,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[])
 {
@@ -393,7 +416,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) {
@@ -413,8 +440,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;