From 8e94b1e0fe185cd95e4e4c513192125ddcfea2c0 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 27 Aug 2023 21:51:25 -0400 Subject: [PATCH] Fixes for 4.19 Signed-off-by: Sasha Levin --- ...d-reference-to-clk_rate_exclusive_-g.patch | 146 ++++++++++++++++++ ...avoid-recursive-lock-during-fence-si.patch | 81 ++++++++++ queue-4.19/series | 2 + 3 files changed, 229 insertions(+) create mode 100644 queue-4.19/clk-fix-undefined-reference-to-clk_rate_exclusive_-g.patch create mode 100644 queue-4.19/dma-buf-sw_sync-avoid-recursive-lock-during-fence-si.patch diff --git a/queue-4.19/clk-fix-undefined-reference-to-clk_rate_exclusive_-g.patch b/queue-4.19/clk-fix-undefined-reference-to-clk_rate_exclusive_-g.patch new file mode 100644 index 00000000000..9ec7d11dccf --- /dev/null +++ b/queue-4.19/clk-fix-undefined-reference-to-clk_rate_exclusive_-g.patch @@ -0,0 +1,146 @@ +From 91042e4804f18dc6968419e2c68816ba210b6af8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Jul 2023 18:51:40 +0100 +Subject: clk: Fix undefined reference to `clk_rate_exclusive_{get,put}' + +From: Biju Das + +[ Upstream commit 2746f13f6f1df7999001d6595b16f789ecc28ad1 ] + +The COMMON_CLK config is not enabled in some of the architectures. +This causes below build issues: + +pwm-rz-mtu3.c:(.text+0x114): +undefined reference to `clk_rate_exclusive_put' +pwm-rz-mtu3.c:(.text+0x32c): +undefined reference to `clk_rate_exclusive_get' + +Fix these issues by moving clk_rate_exclusive_{get,put} inside COMMON_CLK +code block, as clk.c is enabled by COMMON_CLK. + +Fixes: 55e9b8b7b806 ("clk: add clk_rate_exclusive api") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/all/202307251752.vLfmmhYm-lkp@intel.com/ +Signed-off-by: Biju Das +Link: https://lore.kernel.org/r/20230725175140.361479-1-biju.das.jz@bp.renesas.com +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + include/linux/clk.h | 80 ++++++++++++++++++++++----------------------- + 1 file changed, 40 insertions(+), 40 deletions(-) + +diff --git a/include/linux/clk.h b/include/linux/clk.h +index 4f750c481b82b..0a2382d3f68c8 100644 +--- a/include/linux/clk.h ++++ b/include/linux/clk.h +@@ -175,6 +175,39 @@ int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale); + */ + bool clk_is_match(const struct clk *p, const struct clk *q); + ++/** ++ * clk_rate_exclusive_get - get exclusivity over the rate control of a ++ * producer ++ * @clk: clock source ++ * ++ * This function allows drivers to get exclusive control over the rate of a ++ * provider. It prevents any other consumer to execute, even indirectly, ++ * opereation which could alter the rate of the provider or cause glitches ++ * ++ * If exlusivity is claimed more than once on clock, even by the same driver, ++ * the rate effectively gets locked as exclusivity can't be preempted. ++ * ++ * Must not be called from within atomic context. ++ * ++ * Returns success (0) or negative errno. ++ */ ++int clk_rate_exclusive_get(struct clk *clk); ++ ++/** ++ * clk_rate_exclusive_put - release exclusivity over the rate control of a ++ * producer ++ * @clk: clock source ++ * ++ * This function allows drivers to release the exclusivity it previously got ++ * from clk_rate_exclusive_get() ++ * ++ * The caller must balance the number of clk_rate_exclusive_get() and ++ * clk_rate_exclusive_put() calls. ++ * ++ * Must not be called from within atomic context. ++ */ ++void clk_rate_exclusive_put(struct clk *clk); ++ + #else + + static inline int clk_notifier_register(struct clk *clk, +@@ -221,6 +254,13 @@ static inline bool clk_is_match(const struct clk *p, const struct clk *q) + return p == q; + } + ++static inline int clk_rate_exclusive_get(struct clk *clk) ++{ ++ return 0; ++} ++ ++static inline void clk_rate_exclusive_put(struct clk *clk) {} ++ + #endif + + /** +@@ -364,38 +404,6 @@ struct clk *devm_clk_get(struct device *dev, const char *id); + */ + struct clk *devm_get_clk_from_child(struct device *dev, + struct device_node *np, const char *con_id); +-/** +- * clk_rate_exclusive_get - get exclusivity over the rate control of a +- * producer +- * @clk: clock source +- * +- * This function allows drivers to get exclusive control over the rate of a +- * provider. It prevents any other consumer to execute, even indirectly, +- * opereation which could alter the rate of the provider or cause glitches +- * +- * If exlusivity is claimed more than once on clock, even by the same driver, +- * the rate effectively gets locked as exclusivity can't be preempted. +- * +- * Must not be called from within atomic context. +- * +- * Returns success (0) or negative errno. +- */ +-int clk_rate_exclusive_get(struct clk *clk); +- +-/** +- * clk_rate_exclusive_put - release exclusivity over the rate control of a +- * producer +- * @clk: clock source +- * +- * This function allows drivers to release the exclusivity it previously got +- * from clk_rate_exclusive_get() +- * +- * The caller must balance the number of clk_rate_exclusive_get() and +- * clk_rate_exclusive_put() calls. +- * +- * Must not be called from within atomic context. +- */ +-void clk_rate_exclusive_put(struct clk *clk); + + /** + * clk_enable - inform the system when the clock source should be running. +@@ -665,14 +673,6 @@ static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {} + + static inline void devm_clk_put(struct device *dev, struct clk *clk) {} + +- +-static inline int clk_rate_exclusive_get(struct clk *clk) +-{ +- return 0; +-} +- +-static inline void clk_rate_exclusive_put(struct clk *clk) {} +- + static inline int clk_enable(struct clk *clk) + { + return 0; +-- +2.40.1 + diff --git a/queue-4.19/dma-buf-sw_sync-avoid-recursive-lock-during-fence-si.patch b/queue-4.19/dma-buf-sw_sync-avoid-recursive-lock-during-fence-si.patch new file mode 100644 index 00000000000..f588fb3c53d --- /dev/null +++ b/queue-4.19/dma-buf-sw_sync-avoid-recursive-lock-during-fence-si.patch @@ -0,0 +1,81 @@ +From 728f5cec4e9f4e37eb1788deea743dd1152017eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Aug 2023 07:59:38 -0700 +Subject: dma-buf/sw_sync: Avoid recursive lock during fence signal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rob Clark + +[ Upstream commit e531fdb5cd5ee2564b7fe10c8a9219e2b2fac61e ] + +If a signal callback releases the sw_sync fence, that will trigger a +deadlock as the timeline_fence_release recurses onto the fence->lock +(used both for signaling and the the timeline tree). + +To avoid that, temporarily hold an extra reference to the signalled +fences until after we drop the lock. + +(This is an alternative implementation of https://patchwork.kernel.org/patch/11664717/ +which avoids some potential UAF issues with the original patch.) + +v2: Remove now obsolete comment, use list_move_tail() and + list_del_init() + +Reported-by: Bas Nieuwenhuizen +Fixes: d3c6dd1fb30d ("dma-buf/sw_sync: Synchronize signal vs syncpt free") +Signed-off-by: Rob Clark +Link: https://patchwork.freedesktop.org/patch/msgid/20230818145939.39697-1-robdclark@gmail.com +Reviewed-by: Christian König +Signed-off-by: Christian König +Signed-off-by: Sasha Levin +--- + drivers/dma-buf/sw_sync.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c +index 81ba4eb348909..09d369306ee36 100644 +--- a/drivers/dma-buf/sw_sync.c ++++ b/drivers/dma-buf/sw_sync.c +@@ -200,6 +200,7 @@ static const struct dma_fence_ops timeline_fence_ops = { + */ + static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) + { ++ LIST_HEAD(signalled); + struct sync_pt *pt, *next; + + trace_sync_timeline(obj); +@@ -212,21 +213,20 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) + if (!timeline_fence_signaled(&pt->base)) + break; + +- list_del_init(&pt->link); ++ dma_fence_get(&pt->base); ++ ++ list_move_tail(&pt->link, &signalled); + rb_erase(&pt->node, &obj->pt_tree); + +- /* +- * A signal callback may release the last reference to this +- * fence, causing it to be freed. That operation has to be +- * last to avoid a use after free inside this loop, and must +- * be after we remove the fence from the timeline in order to +- * prevent deadlocking on timeline->lock inside +- * timeline_fence_release(). +- */ + dma_fence_signal_locked(&pt->base); + } + + spin_unlock_irq(&obj->lock); ++ ++ list_for_each_entry_safe(pt, next, &signalled, link) { ++ list_del_init(&pt->link); ++ dma_fence_put(&pt->base); ++ } + } + + /** +-- +2.40.1 + diff --git a/queue-4.19/series b/queue-4.19/series index 61b2cbe6257..04d662c29b7 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -123,3 +123,5 @@ sched-rt-pick_next_rt_entity-check-list_entry.patch netfilter-nf_queue-fix-socket-leak.patch rtnetlink-reject-negative-ifindexes-in-rtm_newlink.patch irqchip-mips-gic-don-t-touch-vl_map-if-a-local-interrupt-is-not-routable.patch +clk-fix-undefined-reference-to-clk_rate_exclusive_-g.patch +dma-buf-sw_sync-avoid-recursive-lock-during-fence-si.patch -- 2.47.3