소스 검색

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>
Christian König 10 년 전
부모
커밋
d52cdfa4a0
1개의 변경된 파일31개의 추가작업 그리고 2개의 파일을 삭제
  1. 31 2
      drivers/gpu/drm/radeon/radeon_uvd.c

+ 31 - 2
drivers/gpu/drm/radeon/radeon_uvd.c

@@ -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;