diff --git a/patch/kernel/rockchip-rk3588-legacy/0001-dma-buf-add-dma_resv_get_singleton-v2.patch b/patch/kernel/rockchip-rk3588-legacy/0001-dma-buf-add-dma_resv_get_singleton-v2.patch new file mode 100644 index 0000000000..0c81695803 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-legacy/0001-dma-buf-add-dma_resv_get_singleton-v2.patch @@ -0,0 +1,115 @@ +From 628b9127e29ac2a00852a59e13d45108c5c4e778 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Wed, 3 Nov 2021 10:02:08 +0100 +Subject: [PATCH 1/5] dma-buf: add dma_resv_get_singleton v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a function to simplify getting a single fence for all the fences in +the dma_resv object. + +v2: fix ref leak in error handling + +Signed-off-by: Christian König +Reviewed-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20220321135856.1331-3-christian.koenig@amd.com +(cherry picked from commit 92cedee6a6a3e6fcc3ffc0e3866baae5f6f76ac1) +--- + drivers/dma-buf/dma-resv.c | 59 ++++++++++++++++++++++++++++++++++++++ + include/linux/dma-resv.h | 2 ++ + 2 files changed, 61 insertions(+) + +diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c +index 1187e5e80ede..4c4ec20b99f7 100644 +--- a/drivers/dma-buf/dma-resv.c ++++ b/drivers/dma-buf/dma-resv.c +@@ -33,6 +33,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -517,6 +518,64 @@ int dma_resv_get_fences_rcu(struct dma_resv *obj, + } + EXPORT_SYMBOL_GPL(dma_resv_get_fences_rcu); + ++/** ++ * dma_resv_get_singleton - Get a single fence for all the fences ++ * @obj: the reservation object ++ * @write: true if we should return all fences ++ * @fence: the resulting fence ++ * ++ * Get a single fence representing all the fences inside the resv object. ++ * Returns either 0 for success or -ENOMEM. ++ * ++ * Warning: This can't be used like this when adding the fence back to the resv ++ * object since that can lead to stack corruption when finalizing the ++ * dma_fence_array. ++ * ++ * Returns 0 on success and negative error values on failure. ++ */ ++int dma_resv_get_singleton(struct dma_resv *obj, bool write, ++ struct dma_fence **fence) ++{ ++ struct dma_fence_array *array; ++ struct dma_fence **fences; ++ unsigned count; ++ int r; ++ ++ if (!write) { ++ *fence = dma_resv_get_excl_rcu(obj); ++ return 0; ++ } ++ ++ r = dma_resv_get_fences_rcu(obj, NULL, &count, &fences); ++ if (r) ++ return r; ++ ++ if (count == 0) { ++ *fence = NULL; ++ return 0; ++ } ++ ++ if (count == 1) { ++ *fence = fences[0]; ++ kfree(fences); ++ return 0; ++ } ++ ++ array = dma_fence_array_create(count, fences, ++ dma_fence_context_alloc(1), ++ 1, false); ++ if (!array) { ++ while (count--) ++ dma_fence_put(fences[count]); ++ kfree(fences); ++ return -ENOMEM; ++ } ++ ++ *fence = &array->base; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(dma_resv_get_singleton); ++ + /** + * dma_resv_wait_timeout_rcu - Wait on reservation's objects + * shared and/or exclusive fences. +diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h +index d44a77e8a7e3..171ff5e7ff88 100644 +--- a/include/linux/dma-resv.h ++++ b/include/linux/dma-resv.h +@@ -283,6 +283,8 @@ int dma_resv_get_fences_rcu(struct dma_resv *obj, + unsigned *pshared_count, + struct dma_fence ***pshared); + ++int dma_resv_get_singleton(struct dma_resv *obj, bool write, ++ struct dma_fence **fence); + int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src); + + long dma_resv_wait_timeout_rcu(struct dma_resv *obj, bool wait_all, bool intr, +-- +2.38.1 + diff --git a/patch/kernel/rockchip-rk3588-legacy/0002-dma-buf-Add-an-API-for-exporting-sync-files-v14.patch b/patch/kernel/rockchip-rk3588-legacy/0002-dma-buf-Add-an-API-for-exporting-sync-files-v14.patch new file mode 100644 index 0000000000..e2705d388d --- /dev/null +++ b/patch/kernel/rockchip-rk3588-legacy/0002-dma-buf-Add-an-API-for-exporting-sync-files-v14.patch @@ -0,0 +1,264 @@ +From e2efe6b72f4ceb3511dcd847a172d47d59ce2ed1 Mon Sep 17 00:00:00 2001 +From: Jason Ekstrand +Date: Wed, 8 Jun 2022 10:21:41 -0500 +Subject: [PATCH 2/5] dma-buf: Add an API for exporting sync files (v14) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Modern userspace APIs like Vulkan are built on an explicit +synchronization model. This doesn't always play nicely with the +implicit synchronization used in the kernel and assumed by X11 and +Wayland. The client -> compositor half of the synchronization isn't too +bad, at least on intel, because we can control whether or not i915 +synchronizes on the buffer and whether or not it's considered written. + +The harder part is the compositor -> client synchronization when we get +the buffer back from the compositor. We're required to be able to +provide the client with a VkSemaphore and VkFence representing the point +in time where the window system (compositor and/or display) finished +using the buffer. With current APIs, it's very hard to do this in such +a way that we don't get confused by the Vulkan driver's access of the +buffer. In particular, once we tell the kernel that we're rendering to +the buffer again, any CPU waits on the buffer or GPU dependencies will +wait on some of the client rendering and not just the compositor. + +This new IOCTL solves this problem by allowing us to get a snapshot of +the implicit synchronization state of a given dma-buf in the form of a +sync file. It's effectively the same as a poll() or I915_GEM_WAIT only, +instead of CPU waiting directly, it encapsulates the wait operation, at +the current moment in time, in a sync_file so we can check/wait on it +later. As long as the Vulkan driver does the sync_file export from the +dma-buf before we re-introduce it for rendering, it will only contain +fences from the compositor or display. This allows to accurately turn +it into a VkFence or VkSemaphore without any over-synchronization. + +By making this an ioctl on the dma-buf itself, it allows this new +functionality to be used in an entirely driver-agnostic way without +having access to a DRM fd. This makes it ideal for use in driver-generic +code in Mesa or in a client such as a compositor where the DRM fd may be +hard to reach. + +v2 (Jason Ekstrand): + - Use a wrapper dma_fence_array of all fences including the new one + when importing an exclusive fence. + +v3 (Jason Ekstrand): + - Lock around setting shared fences as well as exclusive + - Mark SIGNAL_SYNC_FILE as a read-write ioctl. + - Initialize ret to 0 in dma_buf_wait_sync_file + +v4 (Jason Ekstrand): + - Use the new dma_resv_get_singleton helper + +v5 (Jason Ekstrand): + - Rename the IOCTLs to import/export rather than wait/signal + - Drop the WRITE flag and always get/set the exclusive fence + +v6 (Jason Ekstrand): + - Drop the sync_file import as it was all-around sketchy and not nearly + as useful as import. + - Re-introduce READ/WRITE flag support for export + - Rework the commit message + +v7 (Jason Ekstrand): + - Require at least one sync flag + - Fix a refcounting bug: dma_resv_get_excl() doesn't take a reference + - Use _rcu helpers since we're accessing the dma_resv read-only + +v8 (Jason Ekstrand): + - Return -ENOMEM if the sync_file_create fails + - Predicate support on IS_ENABLED(CONFIG_SYNC_FILE) + +v9 (Jason Ekstrand): + - Add documentation for the new ioctl + +v10 (Jason Ekstrand): + - Go back to dma_buf_sync_file as the ioctl struct name + +v11 (Daniel Vetter): + - Go back to dma_buf_export_sync_file as the ioctl struct name + - Better kerneldoc describing what the read/write flags do + +v12 (Christian König): + - Document why we chose to make it an ioctl on dma-buf + +v13 (Jason Ekstrand): + - Rebase on Christian König's fence rework + +v14 (Daniel Vetter & Christian König): + - Use dma_rev_usage_rw to get the properly inverted usage to pass to + dma_resv_get_singleton() + - Clean up the sync_file and fd if copy_to_user() fails + +Signed-off-by: Jason Ekstrand +Signed-off-by: Jason Ekstrand +Signed-off-by: Jason Ekstrand +Acked-by: Simon Ser +Reviewed-by: Christian König +Reviewed-by: Daniel Vetter +Cc: Sumit Semwal +Cc: Maarten Lankhorst +Signed-off-by: Simon Ser +Link: https://patchwork.freedesktop.org/patch/msgid/20220608152142.14495-2-jason@jlekstrand.net +(cherry picked from commit 20e10881a043af63f2962a9e6bca64661225b383) +--- + drivers/dma-buf/dma-buf.c | 67 ++++++++++++++++++++++++++++++++++++ + include/uapi/linux/dma-buf.h | 35 +++++++++++++++++++ + 2 files changed, 102 insertions(+) + +diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c +index 023f34ed98af..437f3620dce8 100644 +--- a/drivers/dma-buf/dma-buf.c ++++ b/drivers/dma-buf/dma-buf.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -266,6 +267,9 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence) + * Note that this only signals the completion of the respective fences, i.e. the + * DMA transfers are complete. Cache flushing and any other necessary + * preparations before CPU access can begin still need to happen. ++ * ++ * As an alternative to poll(), the set of fences on DMA buffer can be ++ * exported as a &sync_file using &dma_buf_sync_file_export. + */ + + static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb) +@@ -463,6 +467,64 @@ static long dma_buf_set_name_user(struct dma_buf *dmabuf, const char __user *buf + return ret; + } + ++#if IS_ENABLED(CONFIG_SYNC_FILE) ++static long dma_buf_export_sync_file(struct dma_buf *dmabuf, ++ void __user *user_data) ++{ ++ struct dma_buf_export_sync_file arg; ++ struct dma_fence *fence = NULL; ++ struct sync_file *sync_file; ++ bool write; ++ int fd, ret; ++ ++ if (copy_from_user(&arg, user_data, sizeof(arg))) ++ return -EFAULT; ++ ++ if (arg.flags & ~DMA_BUF_SYNC_RW) ++ return -EINVAL; ++ ++ if ((arg.flags & DMA_BUF_SYNC_RW) == 0) ++ return -EINVAL; ++ ++ fd = get_unused_fd_flags(O_CLOEXEC); ++ if (fd < 0) ++ return fd; ++ ++ write = (arg.flags & DMA_BUF_SYNC_WRITE); ++ ret = dma_resv_get_singleton(dmabuf->resv, write, &fence); ++ if (ret) ++ goto err_put_fd; ++ ++ if (!fence) ++ fence = dma_fence_get_stub(); ++ ++ sync_file = sync_file_create(fence); ++ ++ dma_fence_put(fence); ++ ++ if (!sync_file) { ++ ret = -ENOMEM; ++ goto err_put_fd; ++ } ++ ++ arg.fd = fd; ++ if (copy_to_user(user_data, &arg, sizeof(arg))) { ++ ret = -EFAULT; ++ goto err_put_file; ++ } ++ ++ fd_install(fd, sync_file->file); ++ ++ return 0; ++ ++err_put_file: ++ fput(sync_file->file); ++err_put_fd: ++ put_unused_fd(fd); ++ return ret; ++} ++#endif ++ + static long dma_buf_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) + { +@@ -545,6 +607,11 @@ static long dma_buf_ioctl(struct file *file, + + return ret; + ++#if IS_ENABLED(CONFIG_SYNC_FILE) ++ case DMA_BUF_IOCTL_EXPORT_SYNC_FILE: ++ return dma_buf_export_sync_file(dmabuf, (void __user *)arg); ++#endif ++ + default: + return -ENOTTY; + } +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index 6236c644624d..522bcee5498e 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -37,6 +37,40 @@ struct dma_buf_sync { + + #define DMA_BUF_NAME_LEN 32 + ++/** ++ * struct dma_buf_export_sync_file - Get a sync_file from a dma-buf ++ * ++ * Userspace can perform a DMA_BUF_IOCTL_EXPORT_SYNC_FILE to retrieve the ++ * current set of fences on a dma-buf file descriptor as a sync_file. CPU ++ * waits via poll() or other driver-specific mechanisms typically wait on ++ * whatever fences are on the dma-buf at the time the wait begins. This ++ * is similar except that it takes a snapshot of the current fences on the ++ * dma-buf for waiting later instead of waiting immediately. This is ++ * useful for modern graphics APIs such as Vulkan which assume an explicit ++ * synchronization model but still need to inter-operate with dma-buf. ++ */ ++struct dma_buf_export_sync_file { ++ /** ++ * @flags: Read/write flags ++ * ++ * Must be DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, or both. ++ * ++ * If DMA_BUF_SYNC_READ is set and DMA_BUF_SYNC_WRITE is not set, ++ * the returned sync file waits on any writers of the dma-buf to ++ * complete. Waiting on the returned sync file is equivalent to ++ * poll() with POLLIN. ++ * ++ * If DMA_BUF_SYNC_WRITE is set, the returned sync file waits on ++ * any users of the dma-buf (read or write) to complete. Waiting ++ * on the returned sync file is equivalent to poll() with POLLOUT. ++ * If both DMA_BUF_SYNC_WRITE and DMA_BUF_SYNC_READ are set, this ++ * is equivalent to just DMA_BUF_SYNC_WRITE. ++ */ ++ __u32 flags; ++ /** @fd: Returned sync file descriptor */ ++ __s32 fd; ++}; ++ + #define DMA_BUF_BASE 'b' + #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) + +@@ -46,6 +80,7 @@ struct dma_buf_sync { + #define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *) + #define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32) + #define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64) ++#define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file) + + struct dma_buf_sync_partial { + __u64 flags; +-- +2.38.1 + diff --git a/patch/kernel/rockchip-rk3588-legacy/0003-dma-buf-Add-an-API-for-importing-sync-files-v10.patch b/patch/kernel/rockchip-rk3588-legacy/0003-dma-buf-Add-an-API-for-importing-sync-files-v10.patch new file mode 100644 index 0000000000..52a6a38672 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-legacy/0003-dma-buf-Add-an-API-for-importing-sync-files-v10.patch @@ -0,0 +1,248 @@ +From 520309591712f72a36f87d086f005e9f2c21f388 Mon Sep 17 00:00:00 2001 +From: Jason Ekstrand +Date: Wed, 8 Jun 2022 10:21:42 -0500 +Subject: [PATCH 3/5] dma-buf: Add an API for importing sync files (v10) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch is analogous to the previous sync file export patch in that +it allows you to import a sync_file into a dma-buf. Unlike the previous +patch, however, this does add genuinely new functionality to dma-buf. +Without this, the only way to attach a sync_file to a dma-buf is to +submit a batch to your driver of choice which waits on the sync_file and +claims to write to the dma-buf. Even if said batch is a no-op, a submit +is typically way more overhead than just attaching a fence. A submit +may also imply extra synchronization with other work because it happens +on a hardware queue. + +In the Vulkan world, this is useful for dealing with the out-fence from +vkQueuePresent. Current Linux window-systems (X11, Wayland, etc.) all +rely on dma-buf implicit sync. Since Vulkan is an explicit sync API, we +get a set of fences (VkSemaphores) in vkQueuePresent and have to stash +those as an exclusive (write) fence on the dma-buf. We handle it in +Mesa today with the above mentioned dummy submit trick. This ioctl +would allow us to set it directly without the dummy submit. + +This may also open up possibilities for GPU drivers to move away from +implicit sync for their kernel driver uAPI and instead provide sync +files and rely on dma-buf import/export for communicating with other +implicit sync clients. + +We make the explicit choice here to only allow setting RW fences which +translates to an exclusive fence on the dma_resv. There's no use for +read-only fences for communicating with other implicit sync userspace +and any such attempts are likely to be racy at best. When we got to +insert the RW fence, the actual fence we set as the new exclusive fence +is a combination of the sync_file provided by the user and all the other +fences on the dma_resv. This ensures that the newly added exclusive +fence will never signal before the old one would have and ensures that +we don't break any dma_resv contracts. We require userspace to specify +RW in the flags for symmetry with the export ioctl and in case we ever +want to support read fences in the future. + +There is one downside here that's worth documenting: If two clients +writing to the same dma-buf using this API race with each other, their +actions on the dma-buf may happen in parallel or in an undefined order. +Both with and without this API, the pattern is the same: Collect all +the fences on dma-buf, submit work which depends on said fences, and +then set a new exclusive (write) fence on the dma-buf which depends on +said work. The difference is that, when it's all handled by the GPU +driver's submit ioctl, the three operations happen atomically under the +dma_resv lock. If two userspace submits race, one will happen before +the other. You aren't guaranteed which but you are guaranteed that +they're strictly ordered. If userspace manages the fences itself, then +these three operations happen separately and the two render operations +may happen genuinely in parallel or get interleaved. However, this is a +case of userspace racing with itself. As long as we ensure userspace +can't back the kernel into a corner, it should be fine. + +v2 (Jason Ekstrand): + - Use a wrapper dma_fence_array of all fences including the new one + when importing an exclusive fence. + +v3 (Jason Ekstrand): + - Lock around setting shared fences as well as exclusive + - Mark SIGNAL_SYNC_FILE as a read-write ioctl. + - Initialize ret to 0 in dma_buf_wait_sync_file + +v4 (Jason Ekstrand): + - Use the new dma_resv_get_singleton helper + +v5 (Jason Ekstrand): + - Rename the IOCTLs to import/export rather than wait/signal + - Drop the WRITE flag and always get/set the exclusive fence + +v6 (Jason Ekstrand): + - Split import and export into separate patches + - New commit message + +v7 (Daniel Vetter): + - Fix the uapi header to use the right struct in the ioctl + - Use a separate dma_buf_import_sync_file struct + - Add kerneldoc for dma_buf_import_sync_file + +v8 (Jason Ekstrand): + - Rebase on Christian König's fence rework + +v9 (Daniel Vetter): + - Fix -EINVAL checks for the flags parameter + - Add documentation about read/write fences + - Add documentation about the expected usage of import/export and + specifically call out the possible userspace race. + +v10 (Simon Ser): + - Fix a typo in the docs + +Signed-off-by: Jason Ekstrand +Signed-off-by: Jason Ekstrand +Signed-off-by: Jason Ekstrand +Reviewed-by: Christian König +Reviewed-by: Daniel Vetter +Cc: Sumit Semwal +Cc: Maarten Lankhorst +Signed-off-by: Simon Ser +Link: https://patchwork.freedesktop.org/patch/msgid/20220608152142.14495-3-jason@jlekstrand.net +(cherry picked from commit 594740497e998d30477ab26093bfb81c28cd3ff1) +--- + drivers/dma-buf/dma-buf.c | 42 +++++++++++++++++++++++++++++++ + include/uapi/linux/dma-buf.h | 49 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 91 insertions(+) + +diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c +index 437f3620dce8..41ebb645efda 100644 +--- a/drivers/dma-buf/dma-buf.c ++++ b/drivers/dma-buf/dma-buf.c +@@ -523,6 +523,46 @@ static long dma_buf_export_sync_file(struct dma_buf *dmabuf, + put_unused_fd(fd); + return ret; + } ++ ++static long dma_buf_import_sync_file(struct dma_buf *dmabuf, ++ const void __user *user_data) ++{ ++ struct dma_buf_import_sync_file arg; ++ struct dma_fence *fence; ++ bool write; ++ int ret = 0; ++ ++ if (copy_from_user(&arg, user_data, sizeof(arg))) ++ return -EFAULT; ++ ++ if (arg.flags & ~DMA_BUF_SYNC_RW) ++ return -EINVAL; ++ ++ if ((arg.flags & DMA_BUF_SYNC_RW) == 0) ++ return -EINVAL; ++ ++ fence = sync_file_get_fence(arg.fd); ++ if (!fence) ++ return -EINVAL; ++ ++ write = (arg.flags & DMA_BUF_SYNC_WRITE); ++ ++ dma_resv_lock(dmabuf->resv, NULL); ++ ++ if (write) { ++ dma_resv_add_excl_fence(dmabuf->resv, fence); ++ } else { ++ ret = dma_resv_reserve_shared(dmabuf->resv, 1); ++ if (!ret) ++ dma_resv_add_shared_fence(dmabuf->resv, fence); ++ } ++ ++ dma_resv_unlock(dmabuf->resv); ++ ++ dma_fence_put(fence); ++ ++ return ret; ++} + #endif + + static long dma_buf_ioctl(struct file *file, +@@ -610,6 +650,8 @@ static long dma_buf_ioctl(struct file *file, + #if IS_ENABLED(CONFIG_SYNC_FILE) + case DMA_BUF_IOCTL_EXPORT_SYNC_FILE: + return dma_buf_export_sync_file(dmabuf, (void __user *)arg); ++ case DMA_BUF_IOCTL_IMPORT_SYNC_FILE: ++ return dma_buf_import_sync_file(dmabuf, (const void __user *)arg); + #endif + + default: +diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h +index 522bcee5498e..b4ceeaedfa87 100644 +--- a/include/uapi/linux/dma-buf.h ++++ b/include/uapi/linux/dma-buf.h +@@ -48,6 +48,24 @@ struct dma_buf_sync { + * dma-buf for waiting later instead of waiting immediately. This is + * useful for modern graphics APIs such as Vulkan which assume an explicit + * synchronization model but still need to inter-operate with dma-buf. ++ * ++ * The intended usage pattern is the following: ++ * ++ * 1. Export a sync_file with flags corresponding to the expected GPU usage ++ * via DMA_BUF_IOCTL_EXPORT_SYNC_FILE. ++ * ++ * 2. Submit rendering work which uses the dma-buf. The work should wait on ++ * the exported sync file before rendering and produce another sync_file ++ * when complete. ++ * ++ * 3. Import the rendering-complete sync_file into the dma-buf with flags ++ * corresponding to the GPU usage via DMA_BUF_IOCTL_IMPORT_SYNC_FILE. ++ * ++ * Unlike doing implicit synchronization via a GPU kernel driver's exec ioctl, ++ * the above is not a single atomic operation. If userspace wants to ensure ++ * ordering via these fences, it is the respnosibility of userspace to use ++ * locks or other mechanisms to ensure that no other context adds fences or ++ * submits work between steps 1 and 3 above. + */ + struct dma_buf_export_sync_file { + /** +@@ -71,6 +89,36 @@ struct dma_buf_export_sync_file { + __s32 fd; + }; + ++/** ++ * struct dma_buf_import_sync_file - Insert a sync_file into a dma-buf ++ * ++ * Userspace can perform a DMA_BUF_IOCTL_IMPORT_SYNC_FILE to insert a ++ * sync_file into a dma-buf for the purposes of implicit synchronization ++ * with other dma-buf consumers. This allows clients using explicitly ++ * synchronized APIs such as Vulkan to inter-op with dma-buf consumers ++ * which expect implicit synchronization such as OpenGL or most media ++ * drivers/video. ++ */ ++struct dma_buf_import_sync_file { ++ /** ++ * @flags: Read/write flags ++ * ++ * Must be DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, or both. ++ * ++ * If DMA_BUF_SYNC_READ is set and DMA_BUF_SYNC_WRITE is not set, ++ * this inserts the sync_file as a read-only fence. Any subsequent ++ * implicitly synchronized writes to this dma-buf will wait on this ++ * fence but reads will not. ++ * ++ * If DMA_BUF_SYNC_WRITE is set, this inserts the sync_file as a ++ * write fence. All subsequent implicitly synchronized access to ++ * this dma-buf will wait on this fence. ++ */ ++ __u32 flags; ++ /** @fd: Sync file descriptor */ ++ __s32 fd; ++}; ++ + #define DMA_BUF_BASE 'b' + #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) + +@@ -81,6 +129,7 @@ struct dma_buf_export_sync_file { + #define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32) + #define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64) + #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file) ++#define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file) + + struct dma_buf_sync_partial { + __u64 flags; +-- +2.38.1 + diff --git a/patch/kernel/rockchip-rk3588-legacy/0004-MALI-bifrost-avoid-fence-double-free.patch b/patch/kernel/rockchip-rk3588-legacy/0004-MALI-bifrost-avoid-fence-double-free.patch new file mode 100644 index 0000000000..2a47a7a137 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-legacy/0004-MALI-bifrost-avoid-fence-double-free.patch @@ -0,0 +1,26 @@ +From d1ce2f15fac0e7c3ee27d312016c5fce0608bcae Mon Sep 17 00:00:00 2001 +From: Icecream95 +Date: Tue, 6 Dec 2022 15:17:33 +1300 +Subject: [PATCH 8/9] MALI: bifrost: Avoid fence double-free + +Probably this corresponds to CVE-2022-42716. + +--- + drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c b/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c +index 6c43c029a324..715ccd62e375 100644 +--- a/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c ++++ b/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c +@@ -1550,7 +1550,6 @@ static int kbase_kcpu_fence_signal_prepare( + dma_fence_put(fence_out); + + current_command->info.fence.fence = NULL; +- kfree(fence_out); + + return ret; + } +-- +2.38.1 + diff --git a/patch/kernel/rockchip-rk3588-legacy/0005-drm-rockchip-Re-add-implicit-fencing-support-for-pla.patch b/patch/kernel/rockchip-rk3588-legacy/0005-drm-rockchip-Re-add-implicit-fencing-support-for-pla.patch new file mode 100644 index 0000000000..7d106e8f31 --- /dev/null +++ b/patch/kernel/rockchip-rk3588-legacy/0005-drm-rockchip-Re-add-implicit-fencing-support-for-pla.patch @@ -0,0 +1,40 @@ +From 1a0e71a04479dbd6ef08f46b4911ddc64b47347d Mon Sep 17 00:00:00 2001 +From: Icecream95 +Date: Tue, 6 Dec 2022 16:52:06 +1300 +Subject: [PATCH 5/5] drm/rockchip: Re-add implicit fencing support for planes + +Similar to 63d5e06aa381 ("drm/rockchip: Add implicit fencing support +for planes") but after the code was removed and VOP2 was added in the +downstream kernel. + +Note that upstream VOP2 does not have this line as it was added since +29a840842743 ("drm/: drm_gem_plane_helper_prepare_fb is now +the default") removed the need. + +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +index df4a3291d3da..f9675d9320d4 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -4622,6 +4623,7 @@ static const struct drm_plane_helper_funcs vop2_plane_helper_funcs = { + .atomic_check = vop2_plane_atomic_check, + .atomic_update = vop2_plane_atomic_update, + .atomic_disable = vop2_plane_atomic_disable, ++ .prepare_fb = drm_gem_fb_prepare_fb, + }; + + /** +-- +2.38.1 +