From: Sasha Levin Date: Wed, 5 Jun 2024 11:45:51 +0000 (-0400) Subject: Drop broken timer backport from 6.1 X-Git-Tag: v6.1.93~47 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bad72d8bed627fc7c5df1d2661ed4477f001dd7b;p=thirdparty%2Fkernel%2Fstable-queue.git Drop broken timer backport from 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/series b/queue-6.1/series index 00349b23ac8..526cbaec16d 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -320,11 +320,6 @@ perf-intel-pt-fix-unassigned-instruction-op-discover.patch ovl-remove-upper-umask-handling-from-ovl_create_uppe.patch vmci-fix-an-error-handling-path-in-vmci_guest_probe_.patch dt-bindings-pinctrl-mediatek-mt7622-fix-array-proper.patch -timers-replace-in_irq-with-in_hardirq.patch -timers-split-try_to_-del_timer-_sync-to-prepare-for-.patch -timers-add-shutdown-mechanism-to-the-internal-functi.patch -timers-provide-timer_shutdown-_sync.patch -watchdog-cpu5wdt.c-fix-use-after-free-bug-caused-by-.patch watchdog-bd9576-drop-always-running-property.patch watchdog-sa1100-fix-ptr_err_or_zero-vs-null-check-in.patch usb-gadget-u_audio-fix-race-condition-use-of-control.patch diff --git a/queue-6.1/timers-add-shutdown-mechanism-to-the-internal-functi.patch b/queue-6.1/timers-add-shutdown-mechanism-to-the-internal-functi.patch deleted file mode 100644 index 7eb01183408..00000000000 --- a/queue-6.1/timers-add-shutdown-mechanism-to-the-internal-functi.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 0a23c8adcd36fd438fc1774d2e8b8511e7f6bc32 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 23 Nov 2022 21:18:52 +0100 -Subject: timers: Add shutdown mechanism to the internal functions - -From: Thomas Gleixner - -[ Upstream commit 0cc04e80458a822300b93f82ed861a513edde194 ] - -Tearing down timers which have circular dependencies to other -functionality, e.g. workqueues, where the timer can schedule work and work -can arm timers, is not trivial. - -In those cases it is desired to shutdown the timer in a way which prevents -rearming of the timer. The mechanism to do so is to set timer->function to -NULL and use this as an indicator for the timer arming functions to ignore -the (re)arm request. - -Add a shutdown argument to the relevant internal functions which makes the -actual deactivation code set timer->function to NULL which in turn prevents -rearming of the timer. - -Co-developed-by: Steven Rostedt -Signed-off-by: Steven Rostedt -Signed-off-by: Thomas Gleixner -Tested-by: Guenter Roeck -Reviewed-by: Jacob Keller -Reviewed-by: Anna-Maria Behnsen -Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home -Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org -Link: https://lore.kernel.org/r/20221123201625.253883224@linutronix.de -Stable-dep-of: 573601521277 ("watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger") -Signed-off-by: Sasha Levin ---- - kernel/time/timer.c | 62 +++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 54 insertions(+), 8 deletions(-) - -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index 7a73802d946f1..d1e90c4f3a384 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -1257,12 +1257,19 @@ EXPORT_SYMBOL_GPL(add_timer_on); - /** - * __timer_delete - Internal function: Deactivate a timer - * @timer: The timer to be deactivated -+ * @shutdown: If true, this indicates that the timer is about to be -+ * shutdown permanently. -+ * -+ * If @shutdown is true then @timer->function is set to NULL under the -+ * timer base lock which prevents further rearming of the time. In that -+ * case any attempt to rearm @timer after this function returns will be -+ * silently ignored. - * - * Return: - * * %0 - The timer was not pending - * * %1 - The timer was pending and deactivated - */ --static int __timer_delete(struct timer_list *timer) -+static int __timer_delete(struct timer_list *timer, bool shutdown) - { - struct timer_base *base; - unsigned long flags; -@@ -1270,9 +1277,22 @@ static int __timer_delete(struct timer_list *timer) - - debug_assert_init(timer); - -- if (timer_pending(timer)) { -+ /* -+ * If @shutdown is set then the lock has to be taken whether the -+ * timer is pending or not to protect against a concurrent rearm -+ * which might hit between the lockless pending check and the lock -+ * aquisition. By taking the lock it is ensured that such a newly -+ * enqueued timer is dequeued and cannot end up with -+ * timer->function == NULL in the expiry code. -+ * -+ * If timer->function is currently executed, then this makes sure -+ * that the callback cannot requeue the timer. -+ */ -+ if (timer_pending(timer) || shutdown) { - base = lock_timer_base(timer, &flags); - ret = detach_if_pending(timer, base, true); -+ if (shutdown) -+ timer->function = NULL; - raw_spin_unlock_irqrestore(&base->lock, flags); - } - -@@ -1295,20 +1315,31 @@ static int __timer_delete(struct timer_list *timer) - */ - int timer_delete(struct timer_list *timer) - { -- return __timer_delete(timer); -+ return __timer_delete(timer, false); - } - EXPORT_SYMBOL(timer_delete); - - /** - * __try_to_del_timer_sync - Internal function: Try to deactivate a timer - * @timer: Timer to deactivate -+ * @shutdown: If true, this indicates that the timer is about to be -+ * shutdown permanently. -+ * -+ * If @shutdown is true then @timer->function is set to NULL under the -+ * timer base lock which prevents further rearming of the timer. Any -+ * attempt to rearm @timer after this function returns will be silently -+ * ignored. -+ * -+ * This function cannot guarantee that the timer cannot be rearmed -+ * right after dropping the base lock if @shutdown is false. That -+ * needs to be prevented by the calling code if necessary. - * - * Return: - * * %0 - The timer was not pending - * * %1 - The timer was pending and deactivated - * * %-1 - The timer callback function is running on a different CPU - */ --static int __try_to_del_timer_sync(struct timer_list *timer) -+static int __try_to_del_timer_sync(struct timer_list *timer, bool shutdown) - { - struct timer_base *base; - unsigned long flags; -@@ -1320,6 +1351,8 @@ static int __try_to_del_timer_sync(struct timer_list *timer) - - if (base->running_timer != timer) - ret = detach_if_pending(timer, base, true); -+ if (shutdown) -+ timer->function = NULL; - - raw_spin_unlock_irqrestore(&base->lock, flags); - -@@ -1344,7 +1377,7 @@ static int __try_to_del_timer_sync(struct timer_list *timer) - */ - int try_to_del_timer_sync(struct timer_list *timer) - { -- return __try_to_del_timer_sync(timer); -+ return __try_to_del_timer_sync(timer, false); - } - EXPORT_SYMBOL(try_to_del_timer_sync); - -@@ -1425,12 +1458,25 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } - * __timer_delete_sync - Internal function: Deactivate a timer and wait - * for the handler to finish. - * @timer: The timer to be deactivated -+ * @shutdown: If true, @timer->function will be set to NULL under the -+ * timer base lock which prevents rearming of @timer -+ * -+ * If @shutdown is not set the timer can be rearmed later. If the timer can -+ * be rearmed concurrently, i.e. after dropping the base lock then the -+ * return value is meaningless. -+ * -+ * If @shutdown is set then @timer->function is set to NULL under timer -+ * base lock which prevents rearming of the timer. Any attempt to rearm -+ * a shutdown timer is silently ignored. -+ * -+ * If the timer should be reused after shutdown it has to be initialized -+ * again. - * - * Return: - * * %0 - The timer was not pending - * * %1 - The timer was pending and deactivated - */ --static int __timer_delete_sync(struct timer_list *timer) -+static int __timer_delete_sync(struct timer_list *timer, bool shutdown) - { - int ret; - -@@ -1460,7 +1506,7 @@ static int __timer_delete_sync(struct timer_list *timer) - lockdep_assert_preemption_enabled(); - - do { -- ret = __try_to_del_timer_sync(timer); -+ ret = __try_to_del_timer_sync(timer, shutdown); - - if (unlikely(ret < 0)) { - del_timer_wait_running(timer); -@@ -1512,7 +1558,7 @@ static int __timer_delete_sync(struct timer_list *timer) - */ - int timer_delete_sync(struct timer_list *timer) - { -- return __timer_delete_sync(timer); -+ return __timer_delete_sync(timer, false); - } - EXPORT_SYMBOL(timer_delete_sync); - --- -2.43.0 - diff --git a/queue-6.1/timers-provide-timer_shutdown-_sync.patch b/queue-6.1/timers-provide-timer_shutdown-_sync.patch deleted file mode 100644 index f8211098586..00000000000 --- a/queue-6.1/timers-provide-timer_shutdown-_sync.patch +++ /dev/null @@ -1,152 +0,0 @@ -From c5df943f2d459424a02c4898485a674a9be446d3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 23 Nov 2022 21:18:53 +0100 -Subject: timers: Provide timer_shutdown[_sync]() - -From: Thomas Gleixner - -[ Upstream commit f571faf6e443b6011ccb585d57866177af1f643c ] - -Tearing down timers which have circular dependencies to other -functionality, e.g. workqueues, where the timer can schedule work and work -can arm timers, is not trivial. - -In those cases it is desired to shutdown the timer in a way which prevents -rearming of the timer. The mechanism to do so is to set timer->function to -NULL and use this as an indicator for the timer arming functions to ignore -the (re)arm request. - -Expose new interfaces for this: timer_shutdown_sync() and timer_shutdown(). - -timer_shutdown_sync() has the same functionality as timer_delete_sync() -plus the NULL-ification of the timer function. - -timer_shutdown() has the same functionality as timer_delete() plus the -NULL-ification of the timer function. - -In both cases the rearming of the timer is prevented by silently discarding -rearm attempts due to timer->function being NULL. - -Co-developed-by: Steven Rostedt -Signed-off-by: Steven Rostedt -Signed-off-by: Thomas Gleixner -Tested-by: Guenter Roeck -Reviewed-by: Jacob Keller -Reviewed-by: Anna-Maria Behnsen -Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home -Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org -Link: https://lore.kernel.org/r/20221123201625.314230270@linutronix.de -Stable-dep-of: 573601521277 ("watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger") -Signed-off-by: Sasha Levin ---- - include/linux/timer.h | 2 ++ - kernel/time/timer.c | 66 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 68 insertions(+) - -diff --git a/include/linux/timer.h b/include/linux/timer.h -index e338e173ce8bc..9162f275819a7 100644 ---- a/include/linux/timer.h -+++ b/include/linux/timer.h -@@ -184,6 +184,8 @@ extern void add_timer(struct timer_list *timer); - extern int try_to_del_timer_sync(struct timer_list *timer); - extern int timer_delete_sync(struct timer_list *timer); - extern int timer_delete(struct timer_list *timer); -+extern int timer_shutdown_sync(struct timer_list *timer); -+extern int timer_shutdown(struct timer_list *timer); - - /** - * del_timer_sync - Delete a pending timer and wait for a running callback -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index d1e90c4f3a384..a98630796da8d 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -1319,6 +1319,27 @@ int timer_delete(struct timer_list *timer) - } - EXPORT_SYMBOL(timer_delete); - -+/** -+ * timer_shutdown - Deactivate a timer and prevent rearming -+ * @timer: The timer to be deactivated -+ * -+ * The function does not wait for an eventually running timer callback on a -+ * different CPU but it prevents rearming of the timer. Any attempt to arm -+ * @timer after this function returns will be silently ignored. -+ * -+ * This function is useful for teardown code and should only be used when -+ * timer_shutdown_sync() cannot be invoked due to locking or context constraints. -+ * -+ * Return: -+ * * %0 - The timer was not pending -+ * * %1 - The timer was pending -+ */ -+int timer_shutdown(struct timer_list *timer) -+{ -+ return __timer_delete(timer, true); -+} -+EXPORT_SYMBOL_GPL(timer_shutdown); -+ - /** - * __try_to_del_timer_sync - Internal function: Try to deactivate a timer - * @timer: Timer to deactivate -@@ -1552,6 +1573,9 @@ static int __timer_delete_sync(struct timer_list *timer, bool shutdown) - * lock. If there is the possibility of a concurrent rearm then the return - * value of the function is meaningless. - * -+ * If such a guarantee is needed, e.g. for teardown situations then use -+ * timer_shutdown_sync() instead. -+ * - * Return: - * * %0 - The timer was not pending - * * %1 - The timer was pending and deactivated -@@ -1562,6 +1586,48 @@ int timer_delete_sync(struct timer_list *timer) - } - EXPORT_SYMBOL(timer_delete_sync); - -+/** -+ * timer_shutdown_sync - Shutdown a timer and prevent rearming -+ * @timer: The timer to be shutdown -+ * -+ * When the function returns it is guaranteed that: -+ * - @timer is not queued -+ * - The callback function of @timer is not running -+ * - @timer cannot be enqueued again. Any attempt to rearm -+ * @timer is silently ignored. -+ * -+ * See timer_delete_sync() for synchronization rules. -+ * -+ * This function is useful for final teardown of an infrastructure where -+ * the timer is subject to a circular dependency problem. -+ * -+ * A common pattern for this is a timer and a workqueue where the timer can -+ * schedule work and work can arm the timer. On shutdown the workqueue must -+ * be destroyed and the timer must be prevented from rearming. Unless the -+ * code has conditionals like 'if (mything->in_shutdown)' to prevent that -+ * there is no way to get this correct with timer_delete_sync(). -+ * -+ * timer_shutdown_sync() is solving the problem. The correct ordering of -+ * calls in this case is: -+ * -+ * timer_shutdown_sync(&mything->timer); -+ * workqueue_destroy(&mything->workqueue); -+ * -+ * After this 'mything' can be safely freed. -+ * -+ * This obviously implies that the timer is not required to be functional -+ * for the rest of the shutdown operation. -+ * -+ * Return: -+ * * %0 - The timer was not pending -+ * * %1 - The timer was pending -+ */ -+int timer_shutdown_sync(struct timer_list *timer) -+{ -+ return __timer_delete_sync(timer, true); -+} -+EXPORT_SYMBOL_GPL(timer_shutdown_sync); -+ - static void call_timer_fn(struct timer_list *timer, - void (*fn)(struct timer_list *), - unsigned long baseclk) --- -2.43.0 - diff --git a/queue-6.1/timers-replace-in_irq-with-in_hardirq.patch b/queue-6.1/timers-replace-in_irq-with-in_hardirq.patch deleted file mode 100644 index 5b5261e9691..00000000000 --- a/queue-6.1/timers-replace-in_irq-with-in_hardirq.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c1c90aae953d392c4a876c82731033982d3c2417 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 12 Oct 2022 01:26:29 +0000 -Subject: timers: Replace in_irq() with in_hardirq() - -From: ye xingchen - -[ Upstream commit 8be3f96ceddb911539a53d87a66da84a04502366 ] - -Replace the obsolete and ambiguous macro in_irq() with new -macro in_hardirq(). - -Signed-off-by: ye xingchen -Signed-off-by: Thomas Gleixner -Acked-by: John Stultz -Link: https://lore.kernel.org/r/20221012012629.334966-1-ye.xingchen@zte.com.cn -Stable-dep-of: 573601521277 ("watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger") -Signed-off-by: Sasha Levin ---- - kernel/time/timer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index e09852be4e638..b2d4cb2373ad6 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -1453,7 +1453,7 @@ int timer_delete_sync(struct timer_list *timer) - * don't use it in hardirq context, because it - * could lead to deadlock. - */ -- WARN_ON(in_irq() && !(timer->flags & TIMER_IRQSAFE)); -+ WARN_ON(in_hardirq() && !(timer->flags & TIMER_IRQSAFE)); - - /* - * Must be able to sleep on PREEMPT_RT because of the slowpath in --- -2.43.0 - diff --git a/queue-6.1/timers-split-try_to_-del_timer-_sync-to-prepare-for-.patch b/queue-6.1/timers-split-try_to_-del_timer-_sync-to-prepare-for-.patch deleted file mode 100644 index a4e78972cf8..00000000000 --- a/queue-6.1/timers-split-try_to_-del_timer-_sync-to-prepare-for-.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 74bbe4f47f2d114ba411d4d0ead28ffcabfbd316 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 23 Nov 2022 21:18:50 +0100 -Subject: timers: Split [try_to_]del_timer[_sync]() to prepare for shutdown - mode - -From: Thomas Gleixner - -[ Upstream commit 8553b5f2774a66b1f293b7d783934210afb8f23c ] - -Tearing down timers which have circular dependencies to other -functionality, e.g. workqueues, where the timer can schedule work and work -can arm timers, is not trivial. - -In those cases it is desired to shutdown the timer in a way which prevents -rearming of the timer. The mechanism to do so is to set timer->function to -NULL and use this as an indicator for the timer arming functions to ignore -the (re)arm request. - -Split the inner workings of try_do_del_timer_sync(), del_timer_sync() and -del_timer() into helper functions to prepare for implementing the shutdown -functionality. - -No functional change. - -Co-developed-by: Steven Rostedt -Signed-off-by: Steven Rostedt -Signed-off-by: Thomas Gleixner -Tested-by: Guenter Roeck -Reviewed-by: Jacob Keller -Reviewed-by: Anna-Maria Behnsen -Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home -Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org -Link: https://lore.kernel.org/r/20221123201625.195147423@linutronix.de -Stable-dep-of: 573601521277 ("watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger") -Signed-off-by: Sasha Levin ---- - kernel/time/timer.c | 143 ++++++++++++++++++++++++++++---------------- - 1 file changed, 92 insertions(+), 51 deletions(-) - -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index b2d4cb2373ad6..7a73802d946f1 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -1255,20 +1255,14 @@ void add_timer_on(struct timer_list *timer, int cpu) - EXPORT_SYMBOL_GPL(add_timer_on); - - /** -- * timer_delete - Deactivate a timer -+ * __timer_delete - Internal function: Deactivate a timer - * @timer: The timer to be deactivated - * -- * The function only deactivates a pending timer, but contrary to -- * timer_delete_sync() it does not take into account whether the timer's -- * callback function is concurrently executed on a different CPU or not. -- * It neither prevents rearming of the timer. If @timer can be rearmed -- * concurrently then the return value of this function is meaningless. -- * - * Return: - * * %0 - The timer was not pending - * * %1 - The timer was pending and deactivated - */ --int timer_delete(struct timer_list *timer) -+static int __timer_delete(struct timer_list *timer) - { - struct timer_base *base; - unsigned long flags; -@@ -1284,25 +1278,37 @@ int timer_delete(struct timer_list *timer) - - return ret; - } --EXPORT_SYMBOL(timer_delete); - - /** -- * try_to_del_timer_sync - Try to deactivate a timer -- * @timer: Timer to deactivate -+ * timer_delete - Deactivate a timer -+ * @timer: The timer to be deactivated - * -- * This function tries to deactivate a timer. On success the timer is not -- * queued and the timer callback function is not running on any CPU. -+ * The function only deactivates a pending timer, but contrary to -+ * timer_delete_sync() it does not take into account whether the timer's -+ * callback function is concurrently executed on a different CPU or not. -+ * It neither prevents rearming of the timer. If @timer can be rearmed -+ * concurrently then the return value of this function is meaningless. - * -- * This function does not guarantee that the timer cannot be rearmed right -- * after dropping the base lock. That needs to be prevented by the calling -- * code if necessary. -+ * Return: -+ * * %0 - The timer was not pending -+ * * %1 - The timer was pending and deactivated -+ */ -+int timer_delete(struct timer_list *timer) -+{ -+ return __timer_delete(timer); -+} -+EXPORT_SYMBOL(timer_delete); -+ -+/** -+ * __try_to_del_timer_sync - Internal function: Try to deactivate a timer -+ * @timer: Timer to deactivate - * - * Return: - * * %0 - The timer was not pending - * * %1 - The timer was pending and deactivated - * * %-1 - The timer callback function is running on a different CPU - */ --int try_to_del_timer_sync(struct timer_list *timer) -+static int __try_to_del_timer_sync(struct timer_list *timer) - { - struct timer_base *base; - unsigned long flags; -@@ -1319,6 +1325,27 @@ int try_to_del_timer_sync(struct timer_list *timer) - - return ret; - } -+ -+/** -+ * try_to_del_timer_sync - Try to deactivate a timer -+ * @timer: Timer to deactivate -+ * -+ * This function tries to deactivate a timer. On success the timer is not -+ * queued and the timer callback function is not running on any CPU. -+ * -+ * This function does not guarantee that the timer cannot be rearmed right -+ * after dropping the base lock. That needs to be prevented by the calling -+ * code if necessary. -+ * -+ * Return: -+ * * %0 - The timer was not pending -+ * * %1 - The timer was pending and deactivated -+ * * %-1 - The timer callback function is running on a different CPU -+ */ -+int try_to_del_timer_sync(struct timer_list *timer) -+{ -+ return __try_to_del_timer_sync(timer); -+} - EXPORT_SYMBOL(try_to_del_timer_sync); - - #ifdef CONFIG_PREEMPT_RT -@@ -1395,45 +1422,15 @@ static inline void del_timer_wait_running(struct timer_list *timer) { } - #endif - - /** -- * timer_delete_sync - Deactivate a timer and wait for the handler to finish. -+ * __timer_delete_sync - Internal function: Deactivate a timer and wait -+ * for the handler to finish. - * @timer: The timer to be deactivated - * -- * Synchronization rules: Callers must prevent restarting of the timer, -- * otherwise this function is meaningless. It must not be called from -- * interrupt contexts unless the timer is an irqsafe one. The caller must -- * not hold locks which would prevent completion of the timer's callback -- * function. The timer's handler must not call add_timer_on(). Upon exit -- * the timer is not queued and the handler is not running on any CPU. -- * -- * For !irqsafe timers, the caller must not hold locks that are held in -- * interrupt context. Even if the lock has nothing to do with the timer in -- * question. Here's why:: -- * -- * CPU0 CPU1 -- * ---- ---- -- * -- * call_timer_fn(); -- * base->running_timer = mytimer; -- * spin_lock_irq(somelock); -- * -- * spin_lock(somelock); -- * timer_delete_sync(mytimer); -- * while (base->running_timer == mytimer); -- * -- * Now timer_delete_sync() will never return and never release somelock. -- * The interrupt on the other CPU is waiting to grab somelock but it has -- * interrupted the softirq that CPU0 is waiting to finish. -- * -- * This function cannot guarantee that the timer is not rearmed again by -- * some concurrent or preempting code, right after it dropped the base -- * lock. If there is the possibility of a concurrent rearm then the return -- * value of the function is meaningless. -- * - * Return: - * * %0 - The timer was not pending - * * %1 - The timer was pending and deactivated - */ --int timer_delete_sync(struct timer_list *timer) -+static int __timer_delete_sync(struct timer_list *timer) - { - int ret; - -@@ -1463,7 +1460,7 @@ int timer_delete_sync(struct timer_list *timer) - lockdep_assert_preemption_enabled(); - - do { -- ret = try_to_del_timer_sync(timer); -+ ret = __try_to_del_timer_sync(timer); - - if (unlikely(ret < 0)) { - del_timer_wait_running(timer); -@@ -1473,6 +1470,50 @@ int timer_delete_sync(struct timer_list *timer) - - return ret; - } -+ -+/** -+ * timer_delete_sync - Deactivate a timer and wait for the handler to finish. -+ * @timer: The timer to be deactivated -+ * -+ * Synchronization rules: Callers must prevent restarting of the timer, -+ * otherwise this function is meaningless. It must not be called from -+ * interrupt contexts unless the timer is an irqsafe one. The caller must -+ * not hold locks which would prevent completion of the timer's callback -+ * function. The timer's handler must not call add_timer_on(). Upon exit -+ * the timer is not queued and the handler is not running on any CPU. -+ * -+ * For !irqsafe timers, the caller must not hold locks that are held in -+ * interrupt context. Even if the lock has nothing to do with the timer in -+ * question. Here's why:: -+ * -+ * CPU0 CPU1 -+ * ---- ---- -+ * -+ * call_timer_fn(); -+ * base->running_timer = mytimer; -+ * spin_lock_irq(somelock); -+ * -+ * spin_lock(somelock); -+ * timer_delete_sync(mytimer); -+ * while (base->running_timer == mytimer); -+ * -+ * Now timer_delete_sync() will never return and never release somelock. -+ * The interrupt on the other CPU is waiting to grab somelock but it has -+ * interrupted the softirq that CPU0 is waiting to finish. -+ * -+ * This function cannot guarantee that the timer is not rearmed again by -+ * some concurrent or preempting code, right after it dropped the base -+ * lock. If there is the possibility of a concurrent rearm then the return -+ * value of the function is meaningless. -+ * -+ * Return: -+ * * %0 - The timer was not pending -+ * * %1 - The timer was pending and deactivated -+ */ -+int timer_delete_sync(struct timer_list *timer) -+{ -+ return __timer_delete_sync(timer); -+} - EXPORT_SYMBOL(timer_delete_sync); - - static void call_timer_fn(struct timer_list *timer, --- -2.43.0 - diff --git a/queue-6.1/watchdog-cpu5wdt.c-fix-use-after-free-bug-caused-by-.patch b/queue-6.1/watchdog-cpu5wdt.c-fix-use-after-free-bug-caused-by-.patch deleted file mode 100644 index 24709b7d43a..00000000000 --- a/queue-6.1/watchdog-cpu5wdt.c-fix-use-after-free-bug-caused-by-.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 64803d86c1894e5a41d7fe94b84a54498c3291f9 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 24 Mar 2024 22:04:44 +0800 -Subject: watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger - -From: Duoming Zhou - -[ Upstream commit 573601521277119f2e2ba5f28ae6e87fc594f4d4 ] - -When the cpu5wdt module is removing, the origin code uses del_timer() to -de-activate the timer. If the timer handler is running, del_timer() could -not stop it and will return directly. If the port region is released by -release_region() and then the timer handler cpu5wdt_trigger() calls outb() -to write into the region that is released, the use-after-free bug will -happen. - -Change del_timer() to timer_shutdown_sync() in order that the timer handler -could be finished before the port region is released. - -Fixes: e09d9c3e9f85 ("watchdog: cpu5wdt.c: add missing del_timer call") -Signed-off-by: Duoming Zhou -Reviewed-by: Guenter Roeck -Link: https://lore.kernel.org/r/20240324140444.119584-1-duoming@zju.edu.cn -Signed-off-by: Guenter Roeck -Signed-off-by: Wim Van Sebroeck -Signed-off-by: Sasha Levin ---- - drivers/watchdog/cpu5wdt.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c -index 688b112e712ba..9f279c0e13a66 100644 ---- a/drivers/watchdog/cpu5wdt.c -+++ b/drivers/watchdog/cpu5wdt.c -@@ -252,7 +252,7 @@ static void cpu5wdt_exit(void) - if (cpu5wdt_device.queue) { - cpu5wdt_device.queue = 0; - wait_for_completion(&cpu5wdt_device.stop); -- del_timer(&cpu5wdt_device.timer); -+ timer_shutdown_sync(&cpu5wdt_device.timer); - } - - misc_deregister(&cpu5wdt_misc); --- -2.43.0 -