--- a/sys/dev/drm/radeon/radeon_uvd.c +++ b/sys/dev/drm/radeon/radeon_uvd.c @@ -663,10 +663,27 @@ *data1 = p->idx; break; case UVD_GPCOM_VCPU_CMD: + /* + * DF-4500: every GPCOM command must reference a + * DATA0/DATA1 pair freshly written in this IB. + * 0 is the "unset" sentinel; it can never be a + * legitimate data dword index because dword 0 is + * always the first packet header. Without this + * check an unset or stale index makes us patch the + * first packet header (unvalidated PM4 executes) or + * relocate a (bo, offset) pair the hardware never + * received as a unit. + */ + if (*data0 == 0 || *data1 == 0) { + DRM_ERROR("UVD GPCOM CMD without fresh DATA0/DATA1 pair!\n"); + return -EINVAL; + } r = radeon_uvd_cs_reloc(p, *data0, *data1, buf_sizes, has_msg_cmd); if (r) return r; + *data0 = 0; + *data1 = 0; break; case UVD_ENGINE_CNTL: case UVD_NO_OP: