From 41c454c6e45f0131885110dcf1d7b2d61add91c2 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Mon, 23 Oct 2023 16:27:42 +0300 Subject: [PATCH] gpu: host1x-fence: Skip over stub fences Since kernel 6.1, merging SYNC_FILE FDs will coalesce signaled fences into a stub fence - no longer a host1x fence. To avoid breakage on userspace side, detect such situations here and instead of returning an error, omit such fences when processing. Bug 4199972 Signed-off-by: Mikko Perttunen Change-Id: I22451ffa22c388bbeeb3528e4760730c3f83bc1b Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3002691 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/host1x-fence/dev.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/host1x-fence/dev.c b/drivers/gpu/host1x-fence/dev.c index 31ac7e00..e37c6a3c 100644 --- a/drivers/gpu/host1x-fence/dev.c +++ b/drivers/gpu/host1x-fence/dev.c @@ -119,7 +119,7 @@ static int dev_file_ioctl_fence_extract(struct host1x *host1x, void __user *data struct dma_fence *fence, **fences; struct host1x_fence_extract args; struct dma_fence_array *array; - unsigned int num_fences, i; + unsigned int num_fences, i, j; unsigned long copy_err; int err; @@ -145,21 +145,29 @@ static int dev_file_ioctl_fence_extract(struct host1x *host1x, void __user *data num_fences = 1; } - for (i = 0; i < min(num_fences, args.num_fences); i++) { + for (i = 0, j = 0; i < num_fences; i++) { struct host1x_fence_extract_fence f; err = host1x_fence_extract(fences[i], &f.id, &f.threshold); - if (err) - goto put_fence; - - copy_err = copy_to_user(fences_user_ptr + i, &f, sizeof(f)); - if (copy_err) { - err = -EFAULT; + if (err == -EINVAL && dma_fence_is_signaled(fences[i])) { + /* Likely stub fence */ + continue; + } else if (err) { goto put_fence; } + + if (j < args.num_fences) { + copy_err = copy_to_user(fences_user_ptr + j, &f, sizeof(f)); + if (copy_err) { + err = -EFAULT; + goto put_fence; + } + } + + j++; } - args.num_fences = num_fences; + args.num_fences = j; copy_err = copy_to_user(data, &args, sizeof(args)); if (copy_err) {