mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-23 21:18:46 -04:00
drm/v3d: Reject invalid out_sync handles in submit ioctls
v3d_submit_process_post_deps() looks up the out_sync syncobj via drm_syncobj_find(), and if userspace passes a non-zero handle that doesn't refer to a valid syncobj, the lookup silently returns NULL and the post-deps step skips publishing the submission's last fence to it. The ioctl still returns success, leaving userspace to wait on a invalid syncobj. Instead of silently ignoring an invalid non-zero out_sync, move the syncobj lookup to the submission and make it fail with -ENOENT up front, mirroring the syncobj validation already done for in_sync. Now, v3d_submit_process_post_deps() only does the fence replacement. Note that the lookup is skipped when the multi-sync extension is in use, since args->out_sync is unused in that case. To keep cleanup symmetric on error paths, convert the function v3d_put_multisync_post_deps() into a single function that releases the references that were acquired but never published for both single-sync and multi-sync. Suggested-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Link: https://patch.msgid.link/20260604-v3d-sched-misc-fixes-v4-11-c068f5bf5ccf@igalia.com Signed-off-by: Maíra Canal <mcanal@igalia.com>
This commit is contained in:
@@ -338,17 +338,18 @@ v3d_submit_attach_object_fences(struct v3d_submit *submit)
|
||||
}
|
||||
|
||||
static void
|
||||
v3d_submit_process_post_deps(struct v3d_submit *submit, u32 out_sync,
|
||||
v3d_submit_process_post_deps(struct v3d_submit *submit, struct drm_syncobj *sync_out,
|
||||
struct v3d_submit_ext *se)
|
||||
{
|
||||
bool has_multisync = se && (se->flags & DRM_V3D_EXT_ID_MULTI_SYNC);
|
||||
struct v3d_job *last_job = submit->jobs[submit->job_count - 1];
|
||||
struct drm_syncobj *sync_out;
|
||||
|
||||
/* Make sure single syncobj and multisync are mutually exclusive */
|
||||
WARN_ON_ONCE(sync_out && has_multisync);
|
||||
|
||||
/* Update the return sync object for the job */
|
||||
/* If it only supports a single signal semaphore*/
|
||||
if (!has_multisync) {
|
||||
sync_out = drm_syncobj_find(submit->file_priv, out_sync);
|
||||
if (sync_out) {
|
||||
drm_syncobj_replace_fence(sync_out, last_job->done_fence);
|
||||
drm_syncobj_put(sync_out);
|
||||
@@ -381,7 +382,7 @@ v3d_push_job(struct v3d_job *job)
|
||||
}
|
||||
|
||||
static int
|
||||
v3d_submit_jobs(struct v3d_submit *submit, u32 out_sync,
|
||||
v3d_submit_jobs(struct v3d_submit *submit, struct drm_syncobj *sync_out,
|
||||
struct v3d_submit_ext *se)
|
||||
{
|
||||
struct v3d_dev *v3d = submit->v3d;
|
||||
@@ -406,7 +407,7 @@ v3d_submit_jobs(struct v3d_submit *submit, u32 out_sync,
|
||||
|
||||
v3d_submit_attach_object_fences(submit);
|
||||
v3d_submit_unlock_reservations(submit);
|
||||
v3d_submit_process_post_deps(submit, out_sync, se);
|
||||
v3d_submit_process_post_deps(submit, sync_out, se);
|
||||
|
||||
v3d_submit_put_jobs(submit);
|
||||
|
||||
@@ -444,10 +445,13 @@ v3d_setup_csd_jobs_and_bos(struct v3d_submit *submit,
|
||||
}
|
||||
|
||||
static void
|
||||
v3d_put_multisync_post_deps(struct v3d_submit_ext *se)
|
||||
v3d_submit_put_post_deps(struct drm_syncobj *sync_out, struct v3d_submit_ext *se)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (sync_out)
|
||||
drm_syncobj_put(sync_out);
|
||||
|
||||
if (!(se && se->out_sync_count))
|
||||
return;
|
||||
|
||||
@@ -1006,6 +1010,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||
{
|
||||
struct v3d_submit submit = { .v3d = to_v3d_dev(dev), .file_priv = file_priv };
|
||||
struct drm_v3d_submit_cl *args = data;
|
||||
struct drm_syncobj *sync_out = NULL;
|
||||
struct v3d_submit_ext se = {0};
|
||||
struct v3d_bin_job *bin = NULL;
|
||||
struct v3d_render_job *render;
|
||||
@@ -1032,6 +1037,13 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
/* If multisync is configured, give priority to it and ignore out_sync. */
|
||||
if (args->out_sync && !(se.flags & DRM_V3D_EXT_ID_MULTI_SYNC)) {
|
||||
sync_out = drm_syncobj_find(file_priv, args->out_sync);
|
||||
if (!sync_out)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (args->bcl_start != args->bcl_end) {
|
||||
bin = (struct v3d_bin_job *)v3d_submit_add_job(&submit, V3D_BIN);
|
||||
if (IS_ERR(bin)) {
|
||||
@@ -1088,7 +1100,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = v3d_submit_jobs(&submit, args->out_sync, &se);
|
||||
ret = v3d_submit_jobs(&submit, sync_out, &se);
|
||||
if (ret)
|
||||
goto fail_unreserve;
|
||||
|
||||
@@ -1098,7 +1110,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||
v3d_submit_unlock_reservations(&submit);
|
||||
fail:
|
||||
v3d_submit_cleanup_jobs(&submit);
|
||||
v3d_put_multisync_post_deps(&se);
|
||||
v3d_submit_put_post_deps(sync_out, &se);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1118,6 +1130,7 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
|
||||
{
|
||||
struct v3d_submit submit = { .v3d = to_v3d_dev(dev), .file_priv = file_priv };
|
||||
struct drm_v3d_submit_tfu *args = data;
|
||||
struct drm_syncobj *sync_out = NULL;
|
||||
struct v3d_submit_ext se = {0};
|
||||
struct v3d_tfu_job *job;
|
||||
int ret = 0;
|
||||
@@ -1137,6 +1150,13 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
/* If multisync is configured, give priority to it and ignore out_sync. */
|
||||
if (args->out_sync && !(se.flags & DRM_V3D_EXT_ID_MULTI_SYNC)) {
|
||||
sync_out = drm_syncobj_find(file_priv, args->out_sync);
|
||||
if (!sync_out)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
job = (struct v3d_tfu_job *)v3d_submit_add_job(&submit, V3D_TFU);
|
||||
if (IS_ERR(job)) {
|
||||
ret = PTR_ERR(job);
|
||||
@@ -1178,7 +1198,7 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = v3d_submit_jobs(&submit, args->out_sync, &se);
|
||||
ret = v3d_submit_jobs(&submit, sync_out, &se);
|
||||
if (ret)
|
||||
goto fail_unreserve;
|
||||
|
||||
@@ -1188,7 +1208,7 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
|
||||
v3d_submit_unlock_reservations(&submit);
|
||||
fail:
|
||||
v3d_submit_cleanup_jobs(&submit);
|
||||
v3d_put_multisync_post_deps(&se);
|
||||
v3d_submit_put_post_deps(sync_out, &se);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1208,6 +1228,7 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
|
||||
{
|
||||
struct v3d_submit submit = { .v3d = to_v3d_dev(dev), .file_priv = file_priv };
|
||||
struct drm_v3d_submit_csd *args = data;
|
||||
struct drm_syncobj *sync_out = NULL;
|
||||
struct v3d_submit_ext se = {0};
|
||||
int ret;
|
||||
|
||||
@@ -1234,6 +1255,13 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
/* If multisync is configured, give priority to it and ignore out_sync. */
|
||||
if (args->out_sync && !(se.flags & DRM_V3D_EXT_ID_MULTI_SYNC)) {
|
||||
sync_out = drm_syncobj_find(file_priv, args->out_sync);
|
||||
if (!sync_out)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = v3d_setup_csd_jobs_and_bos(&submit, args, &se);
|
||||
if (ret)
|
||||
goto fail;
|
||||
@@ -1246,7 +1274,7 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = v3d_submit_jobs(&submit, args->out_sync, &se);
|
||||
ret = v3d_submit_jobs(&submit, sync_out, &se);
|
||||
if (ret)
|
||||
goto fail_unreserve;
|
||||
|
||||
@@ -1256,7 +1284,7 @@ v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
|
||||
v3d_submit_unlock_reservations(&submit);
|
||||
fail:
|
||||
v3d_submit_cleanup_jobs(&submit);
|
||||
v3d_put_multisync_post_deps(&se);
|
||||
v3d_submit_put_post_deps(sync_out, &se);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1354,7 +1382,7 @@ v3d_submit_cpu_ioctl(struct drm_device *dev, void *data,
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = v3d_submit_jobs(&submit, 0, &se);
|
||||
ret = v3d_submit_jobs(&submit, NULL, &se);
|
||||
if (ret)
|
||||
goto fail_unreserve;
|
||||
|
||||
@@ -1364,7 +1392,7 @@ v3d_submit_cpu_ioctl(struct drm_device *dev, void *data,
|
||||
v3d_submit_unlock_reservations(&submit);
|
||||
fail:
|
||||
v3d_submit_cleanup_jobs(&submit);
|
||||
v3d_put_multisync_post_deps(&se);
|
||||
v3d_submit_put_post_deps(NULL, &se);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user