+++ /dev/null
-From 4b95adf98f5c5c0219c6eba726aa9626cdb3a351 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 7 Apr 2026 10:54:17 +0200
-Subject: clockevents: Prevent timer interrupt starvation
-
-From: Thomas Gleixner <tglx@kernel.org>
-
-[ Upstream commit d6e152d905bdb1f32f9d99775e2f453350399a6a ]
-
-Calvin reported an odd NMI watchdog lockup which claims that the CPU locked
-up in user space. He provided a reproducer, which sets up a timerfd based
-timer and then rearms it in a loop with an absolute expiry time of 1ns.
-
-As the expiry time is in the past, the timer ends up as the first expiring
-timer in the per CPU hrtimer base and the clockevent device is programmed
-with the minimum delta value. If the machine is fast enough, this ends up
-in a endless loop of programming the delta value to the minimum value
-defined by the clock event device, before the timer interrupt can fire,
-which starves the interrupt and consequently triggers the lockup detector
-because the hrtimer callback of the lockup mechanism is never invoked.
-
-As a first step to prevent this, avoid reprogramming the clock event device
-when:
- - a forced minimum delta event is pending
- - the new expiry delta is less then or equal to the minimum delta
-
-Thanks to Calvin for providing the reproducer and to Borislav for testing
-and providing data from his Zen5 machine.
-
-The problem is not limited to Zen5, but depending on the underlying
-clock event device (e.g. TSC deadline timer on Intel) and the CPU speed
-not necessarily observable.
-
-This change serves only as the last resort and further changes will be made
-to prevent this scenario earlier in the call chain as far as possible.
-
-[ tglx: Updated to restore the old behaviour vs. !force and delta <= 0 and
- fixed up the tick-broadcast handlers as pointed out by Borislav ]
-
-Fixes: d316c57ff6bf ("[PATCH] clockevents: add core functionality")
-Reported-by: Calvin Owens <calvin@wbinvd.org>
-Signed-off-by: Thomas Gleixner <tglx@kernel.org>
-Tested-by: Calvin Owens <calvin@wbinvd.org>
-Tested-by: Borislav Petkov <bp@alien8.de>
-Link: https://lore.kernel.org/lkml/acMe-QZUel-bBYUh@mozart.vkv.me/
-Link: https://patch.msgid.link/20260407083247.562657657@kernel.org
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/clockchips.h | 2 ++
- kernel/time/clockevents.c | 27 +++++++++++++++++++--------
- kernel/time/hrtimer.c | 1 +
- kernel/time/tick-broadcast.c | 8 +++++++-
- kernel/time/tick-common.c | 1 +
- kernel/time/tick-sched.c | 1 +
- 6 files changed, 31 insertions(+), 9 deletions(-)
-
-diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
-index 8ae9a95ebf5b5..046c6d8d91a69 100644
---- a/include/linux/clockchips.h
-+++ b/include/linux/clockchips.h
-@@ -80,6 +80,7 @@ enum clock_event_state {
- * @shift: nanoseconds to cycles divisor (power of two)
- * @state_use_accessors:current state of the device, assigned by the core code
- * @features: features
-+ * @next_event_forced: True if the last programming was a forced event
- * @retries: number of forced programming retries
- * @set_state_periodic: switch state to periodic
- * @set_state_oneshot: switch state to oneshot
-@@ -108,6 +109,7 @@ struct clock_event_device {
- u32 shift;
- enum clock_event_state state_use_accessors;
- unsigned int features;
-+ unsigned int next_event_forced;
- unsigned long retries;
-
- int (*set_state_periodic)(struct clock_event_device *);
-diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
-index 003ccf338d201..a41701ae38126 100644
---- a/kernel/time/clockevents.c
-+++ b/kernel/time/clockevents.c
-@@ -172,6 +172,7 @@ void clockevents_shutdown(struct clock_event_device *dev)
- {
- clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
- }
-
- /**
-@@ -305,7 +306,6 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- {
- unsigned long long clc;
- int64_t delta;
-- int rc;
-
- if (WARN_ON_ONCE(expires < 0))
- return -ETIME;
-@@ -324,16 +324,27 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- return dev->set_next_ktime(expires, dev);
-
- delta = ktime_to_ns(ktime_sub(expires, ktime_get()));
-- if (delta <= 0)
-- return force ? clockevents_program_min_delta(dev) : -ETIME;
-
-- delta = min(delta, (int64_t) dev->max_delta_ns);
-- delta = max(delta, (int64_t) dev->min_delta_ns);
-+ /* Required for tick_periodic() during early boot */
-+ if (delta <= 0 && !force)
-+ return -ETIME;
-+
-+ if (delta > (int64_t)dev->min_delta_ns) {
-+ delta = min(delta, (int64_t) dev->max_delta_ns);
-+ clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-+ if (!dev->set_next_event((unsigned long) clc, dev))
-+ return 0;
-+ }
-
-- clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-- rc = dev->set_next_event((unsigned long) clc, dev);
-+ if (dev->next_event_forced)
-+ return 0;
-
-- return (rc && force) ? clockevents_program_min_delta(dev) : rc;
-+ if (dev->set_next_event(dev->min_delta_ticks, dev)) {
-+ if (!force || clockevents_program_min_delta(dev))
-+ return -ETIME;
-+ }
-+ dev->next_event_forced = 1;
-+ return 0;
- }
-
- /*
-diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
-index 0246b32e907d2..459bd5ab95101 100644
---- a/kernel/time/hrtimer.c
-+++ b/kernel/time/hrtimer.c
-@@ -1788,6 +1788,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
- BUG_ON(!cpu_base->hres_active);
- cpu_base->nr_events++;
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- raw_spin_lock_irqsave(&cpu_base->lock, flags);
- entry_time = now = hrtimer_update_base(cpu_base);
-diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
-index 13a71a894cc16..369f7e52b5e51 100644
---- a/kernel/time/tick-broadcast.c
-+++ b/kernel/time/tick-broadcast.c
-@@ -76,8 +76,10 @@ const struct clock_event_device *tick_get_wakeup_device(int cpu)
- */
- static void tick_broadcast_start_periodic(struct clock_event_device *bc)
- {
-- if (bc)
-+ if (bc) {
-+ bc->next_event_forced = 0;
- tick_setup_periodic(bc, 1);
-+ }
- }
-
- /*
-@@ -403,6 +405,7 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
- bool bc_local;
-
- raw_spin_lock(&tick_broadcast_lock);
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
-
- /* Handle spurious interrupts gracefully */
- if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
-@@ -692,6 +695,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
-
- raw_spin_lock(&tick_broadcast_lock);
- dev->next_event = KTIME_MAX;
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
- next_event = KTIME_MAX;
- cpumask_clear(tmpmask);
- now = ktime_get();
-@@ -1057,6 +1061,7 @@ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc,
-
-
- bc->event_handler = tick_handle_oneshot_broadcast;
-+ bc->next_event_forced = 0;
- bc->next_event = KTIME_MAX;
-
- /*
-@@ -1169,6 +1174,7 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
- }
-
- /* This moves the broadcast assignment to this CPU: */
-+ bc->next_event_forced = 0;
- clockevents_program_event(bc, bc->next_event, 1);
- }
- raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
-index 7f2b17fc8ce40..79ae1adf635bd 100644
---- a/kernel/time/tick-common.c
-+++ b/kernel/time/tick-common.c
-@@ -109,6 +109,7 @@ void tick_handle_periodic(struct clock_event_device *dev)
- int cpu = smp_processor_id();
- ktime_t next = dev->next_event;
-
-+ dev->next_event_forced = 0;
- tick_periodic(cpu);
-
- #if defined(CONFIG_HIGH_RES_TIMERS) || defined(CONFIG_NO_HZ_COMMON)
-diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
-index ae1b207c64479..6a3d0c0c8ffaf 100644
---- a/kernel/time/tick-sched.c
-+++ b/kernel/time/tick-sched.c
-@@ -1354,6 +1354,7 @@ static void tick_nohz_handler(struct clock_event_device *dev)
- ktime_t now = ktime_get();
-
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- tick_sched_do_timer(ts, now);
- tick_sched_handle(ts, regs);
---
-2.53.0
-
l2tp-drop-large-packets-with-udp-encap.patch
gpio-tegra-fix-irq_release_resources-calling-enable-.patch
perf-x86-intel-uncore-skip-discovery-table-for-offli.patch
-clockevents-prevent-timer-interrupt-starvation.patch
crypto-algif_aead-fix-minimum-rx-size-check-for-decr.patch
i3c-fix-uninitialized-variable-use-in-i2c-setup.patch
netfilter-conntrack-add-missing-netlink-policy-valid.patch
+++ /dev/null
-From a53e2c11e05c64e57807aea194c2c4819d1369dd Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 7 Apr 2026 10:54:17 +0200
-Subject: clockevents: Prevent timer interrupt starvation
-
-From: Thomas Gleixner <tglx@kernel.org>
-
-[ Upstream commit d6e152d905bdb1f32f9d99775e2f453350399a6a ]
-
-Calvin reported an odd NMI watchdog lockup which claims that the CPU locked
-up in user space. He provided a reproducer, which sets up a timerfd based
-timer and then rearms it in a loop with an absolute expiry time of 1ns.
-
-As the expiry time is in the past, the timer ends up as the first expiring
-timer in the per CPU hrtimer base and the clockevent device is programmed
-with the minimum delta value. If the machine is fast enough, this ends up
-in a endless loop of programming the delta value to the minimum value
-defined by the clock event device, before the timer interrupt can fire,
-which starves the interrupt and consequently triggers the lockup detector
-because the hrtimer callback of the lockup mechanism is never invoked.
-
-As a first step to prevent this, avoid reprogramming the clock event device
-when:
- - a forced minimum delta event is pending
- - the new expiry delta is less then or equal to the minimum delta
-
-Thanks to Calvin for providing the reproducer and to Borislav for testing
-and providing data from his Zen5 machine.
-
-The problem is not limited to Zen5, but depending on the underlying
-clock event device (e.g. TSC deadline timer on Intel) and the CPU speed
-not necessarily observable.
-
-This change serves only as the last resort and further changes will be made
-to prevent this scenario earlier in the call chain as far as possible.
-
-[ tglx: Updated to restore the old behaviour vs. !force and delta <= 0 and
- fixed up the tick-broadcast handlers as pointed out by Borislav ]
-
-Fixes: d316c57ff6bf ("[PATCH] clockevents: add core functionality")
-Reported-by: Calvin Owens <calvin@wbinvd.org>
-Signed-off-by: Thomas Gleixner <tglx@kernel.org>
-Tested-by: Calvin Owens <calvin@wbinvd.org>
-Tested-by: Borislav Petkov <bp@alien8.de>
-Link: https://lore.kernel.org/lkml/acMe-QZUel-bBYUh@mozart.vkv.me/
-Link: https://patch.msgid.link/20260407083247.562657657@kernel.org
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/clockchips.h | 2 ++
- kernel/time/clockevents.c | 27 +++++++++++++++++++--------
- kernel/time/hrtimer.c | 1 +
- kernel/time/tick-broadcast.c | 8 +++++++-
- kernel/time/tick-common.c | 1 +
- kernel/time/tick-sched.c | 1 +
- 6 files changed, 31 insertions(+), 9 deletions(-)
-
-diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
-index 8ae9a95ebf5b5..046c6d8d91a69 100644
---- a/include/linux/clockchips.h
-+++ b/include/linux/clockchips.h
-@@ -80,6 +80,7 @@ enum clock_event_state {
- * @shift: nanoseconds to cycles divisor (power of two)
- * @state_use_accessors:current state of the device, assigned by the core code
- * @features: features
-+ * @next_event_forced: True if the last programming was a forced event
- * @retries: number of forced programming retries
- * @set_state_periodic: switch state to periodic
- * @set_state_oneshot: switch state to oneshot
-@@ -108,6 +109,7 @@ struct clock_event_device {
- u32 shift;
- enum clock_event_state state_use_accessors;
- unsigned int features;
-+ unsigned int next_event_forced;
- unsigned long retries;
-
- int (*set_state_periodic)(struct clock_event_device *);
-diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
-index 5d85014d59b5f..78cd81a99ea03 100644
---- a/kernel/time/clockevents.c
-+++ b/kernel/time/clockevents.c
-@@ -172,6 +172,7 @@ void clockevents_shutdown(struct clock_event_device *dev)
- {
- clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
- }
-
- /**
-@@ -305,7 +306,6 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- {
- unsigned long long clc;
- int64_t delta;
-- int rc;
-
- if (WARN_ON_ONCE(expires < 0))
- return -ETIME;
-@@ -324,16 +324,27 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- return dev->set_next_ktime(expires, dev);
-
- delta = ktime_to_ns(ktime_sub(expires, ktime_get()));
-- if (delta <= 0)
-- return force ? clockevents_program_min_delta(dev) : -ETIME;
-
-- delta = min(delta, (int64_t) dev->max_delta_ns);
-- delta = max(delta, (int64_t) dev->min_delta_ns);
-+ /* Required for tick_periodic() during early boot */
-+ if (delta <= 0 && !force)
-+ return -ETIME;
-+
-+ if (delta > (int64_t)dev->min_delta_ns) {
-+ delta = min(delta, (int64_t) dev->max_delta_ns);
-+ clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-+ if (!dev->set_next_event((unsigned long) clc, dev))
-+ return 0;
-+ }
-
-- clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-- rc = dev->set_next_event((unsigned long) clc, dev);
-+ if (dev->next_event_forced)
-+ return 0;
-
-- return (rc && force) ? clockevents_program_min_delta(dev) : rc;
-+ if (dev->set_next_event(dev->min_delta_ticks, dev)) {
-+ if (!force || clockevents_program_min_delta(dev))
-+ return -ETIME;
-+ }
-+ dev->next_event_forced = 1;
-+ return 0;
- }
-
- /*
-diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
-index 002b29e566cb3..d5bb051d6e167 100644
---- a/kernel/time/hrtimer.c
-+++ b/kernel/time/hrtimer.c
-@@ -1850,6 +1850,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
- BUG_ON(!cpu_base->hres_active);
- cpu_base->nr_events++;
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- raw_spin_lock_irqsave(&cpu_base->lock, flags);
- entry_time = now = hrtimer_update_base(cpu_base);
-diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
-index 13a71a894cc16..369f7e52b5e51 100644
---- a/kernel/time/tick-broadcast.c
-+++ b/kernel/time/tick-broadcast.c
-@@ -76,8 +76,10 @@ const struct clock_event_device *tick_get_wakeup_device(int cpu)
- */
- static void tick_broadcast_start_periodic(struct clock_event_device *bc)
- {
-- if (bc)
-+ if (bc) {
-+ bc->next_event_forced = 0;
- tick_setup_periodic(bc, 1);
-+ }
- }
-
- /*
-@@ -403,6 +405,7 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
- bool bc_local;
-
- raw_spin_lock(&tick_broadcast_lock);
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
-
- /* Handle spurious interrupts gracefully */
- if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
-@@ -692,6 +695,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
-
- raw_spin_lock(&tick_broadcast_lock);
- dev->next_event = KTIME_MAX;
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
- next_event = KTIME_MAX;
- cpumask_clear(tmpmask);
- now = ktime_get();
-@@ -1057,6 +1061,7 @@ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc,
-
-
- bc->event_handler = tick_handle_oneshot_broadcast;
-+ bc->next_event_forced = 0;
- bc->next_event = KTIME_MAX;
-
- /*
-@@ -1169,6 +1174,7 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
- }
-
- /* This moves the broadcast assignment to this CPU: */
-+ bc->next_event_forced = 0;
- clockevents_program_event(bc, bc->next_event, 1);
- }
- raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
-index 7f2b17fc8ce40..79ae1adf635bd 100644
---- a/kernel/time/tick-common.c
-+++ b/kernel/time/tick-common.c
-@@ -109,6 +109,7 @@ void tick_handle_periodic(struct clock_event_device *dev)
- int cpu = smp_processor_id();
- ktime_t next = dev->next_event;
-
-+ dev->next_event_forced = 0;
- tick_periodic(cpu);
-
- #if defined(CONFIG_HIGH_RES_TIMERS) || defined(CONFIG_NO_HZ_COMMON)
-diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
-index 8cfdc6b978d76..3a017b5555250 100644
---- a/kernel/time/tick-sched.c
-+++ b/kernel/time/tick-sched.c
-@@ -1382,6 +1382,7 @@ static void tick_nohz_handler(struct clock_event_device *dev)
- ktime_t now = ktime_get();
-
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- tick_sched_do_timer(ts, now);
- tick_sched_handle(ts, regs);
---
-2.53.0
-
l2tp-drop-large-packets-with-udp-encap.patch
gpio-tegra-fix-irq_release_resources-calling-enable-.patch
perf-x86-intel-uncore-skip-discovery-table-for-offli.patch
-clockevents-prevent-timer-interrupt-starvation.patch
crypto-algif_aead-fix-minimum-rx-size-check-for-decr.patch
revert-drm-fix-use-after-free-on-framebuffers-and-pr.patch
netfilter-conntrack-add-missing-netlink-policy-valid.patch
+++ /dev/null
-From f0aa641eb7fe25dd725ef6835dde2dd178fc55e8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 7 Apr 2026 10:54:17 +0200
-Subject: clockevents: Prevent timer interrupt starvation
-
-From: Thomas Gleixner <tglx@kernel.org>
-
-[ Upstream commit d6e152d905bdb1f32f9d99775e2f453350399a6a ]
-
-Calvin reported an odd NMI watchdog lockup which claims that the CPU locked
-up in user space. He provided a reproducer, which sets up a timerfd based
-timer and then rearms it in a loop with an absolute expiry time of 1ns.
-
-As the expiry time is in the past, the timer ends up as the first expiring
-timer in the per CPU hrtimer base and the clockevent device is programmed
-with the minimum delta value. If the machine is fast enough, this ends up
-in a endless loop of programming the delta value to the minimum value
-defined by the clock event device, before the timer interrupt can fire,
-which starves the interrupt and consequently triggers the lockup detector
-because the hrtimer callback of the lockup mechanism is never invoked.
-
-As a first step to prevent this, avoid reprogramming the clock event device
-when:
- - a forced minimum delta event is pending
- - the new expiry delta is less then or equal to the minimum delta
-
-Thanks to Calvin for providing the reproducer and to Borislav for testing
-and providing data from his Zen5 machine.
-
-The problem is not limited to Zen5, but depending on the underlying
-clock event device (e.g. TSC deadline timer on Intel) and the CPU speed
-not necessarily observable.
-
-This change serves only as the last resort and further changes will be made
-to prevent this scenario earlier in the call chain as far as possible.
-
-[ tglx: Updated to restore the old behaviour vs. !force and delta <= 0 and
- fixed up the tick-broadcast handlers as pointed out by Borislav ]
-
-Fixes: d316c57ff6bf ("[PATCH] clockevents: add core functionality")
-Reported-by: Calvin Owens <calvin@wbinvd.org>
-Signed-off-by: Thomas Gleixner <tglx@kernel.org>
-Tested-by: Calvin Owens <calvin@wbinvd.org>
-Tested-by: Borislav Petkov <bp@alien8.de>
-Link: https://lore.kernel.org/lkml/acMe-QZUel-bBYUh@mozart.vkv.me/
-Link: https://patch.msgid.link/20260407083247.562657657@kernel.org
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/clockchips.h | 2 ++
- kernel/time/clockevents.c | 27 +++++++++++++++++++--------
- kernel/time/hrtimer.c | 1 +
- kernel/time/tick-broadcast.c | 8 +++++++-
- kernel/time/tick-common.c | 1 +
- kernel/time/tick-sched.c | 1 +
- 6 files changed, 31 insertions(+), 9 deletions(-)
-
-diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
-index b0df28ddd394b..50cdc9da8d32a 100644
---- a/include/linux/clockchips.h
-+++ b/include/linux/clockchips.h
-@@ -80,6 +80,7 @@ enum clock_event_state {
- * @shift: nanoseconds to cycles divisor (power of two)
- * @state_use_accessors:current state of the device, assigned by the core code
- * @features: features
-+ * @next_event_forced: True if the last programming was a forced event
- * @retries: number of forced programming retries
- * @set_state_periodic: switch state to periodic
- * @set_state_oneshot: switch state to oneshot
-@@ -108,6 +109,7 @@ struct clock_event_device {
- u32 shift;
- enum clock_event_state state_use_accessors;
- unsigned int features;
-+ unsigned int next_event_forced;
- unsigned long retries;
-
- int (*set_state_periodic)(struct clock_event_device *);
-diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
-index 78c7bd64d0ddf..6f4257e63bba8 100644
---- a/kernel/time/clockevents.c
-+++ b/kernel/time/clockevents.c
-@@ -172,6 +172,7 @@ void clockevents_shutdown(struct clock_event_device *dev)
- {
- clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
- }
-
- /**
-@@ -305,7 +306,6 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- {
- unsigned long long clc;
- int64_t delta;
-- int rc;
-
- if (WARN_ON_ONCE(expires < 0))
- return -ETIME;
-@@ -324,16 +324,27 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- return dev->set_next_ktime(expires, dev);
-
- delta = ktime_to_ns(ktime_sub(expires, ktime_get()));
-- if (delta <= 0)
-- return force ? clockevents_program_min_delta(dev) : -ETIME;
-
-- delta = min(delta, (int64_t) dev->max_delta_ns);
-- delta = max(delta, (int64_t) dev->min_delta_ns);
-+ /* Required for tick_periodic() during early boot */
-+ if (delta <= 0 && !force)
-+ return -ETIME;
-+
-+ if (delta > (int64_t)dev->min_delta_ns) {
-+ delta = min(delta, (int64_t) dev->max_delta_ns);
-+ clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-+ if (!dev->set_next_event((unsigned long) clc, dev))
-+ return 0;
-+ }
-
-- clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-- rc = dev->set_next_event((unsigned long) clc, dev);
-+ if (dev->next_event_forced)
-+ return 0;
-
-- return (rc && force) ? clockevents_program_min_delta(dev) : rc;
-+ if (dev->set_next_event(dev->min_delta_ticks, dev)) {
-+ if (!force || clockevents_program_min_delta(dev))
-+ return -ETIME;
-+ }
-+ dev->next_event_forced = 1;
-+ return 0;
- }
-
- /*
-diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
-index 640d2ea4bd1fa..7c57fe7d20d9a 100644
---- a/kernel/time/hrtimer.c
-+++ b/kernel/time/hrtimer.c
-@@ -1852,6 +1852,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
- BUG_ON(!cpu_base->hres_active);
- cpu_base->nr_events++;
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- raw_spin_lock_irqsave(&cpu_base->lock, flags);
- entry_time = now = hrtimer_update_base(cpu_base);
-diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
-index ed58eebb4e8f4..99d2978ef9b98 100644
---- a/kernel/time/tick-broadcast.c
-+++ b/kernel/time/tick-broadcast.c
-@@ -76,8 +76,10 @@ const struct clock_event_device *tick_get_wakeup_device(int cpu)
- */
- static void tick_broadcast_start_periodic(struct clock_event_device *bc)
- {
-- if (bc)
-+ if (bc) {
-+ bc->next_event_forced = 0;
- tick_setup_periodic(bc, 1);
-+ }
- }
-
- /*
-@@ -403,6 +405,7 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
- bool bc_local;
-
- raw_spin_lock(&tick_broadcast_lock);
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
-
- /* Handle spurious interrupts gracefully */
- if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
-@@ -696,6 +699,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
-
- raw_spin_lock(&tick_broadcast_lock);
- dev->next_event = KTIME_MAX;
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
- next_event = KTIME_MAX;
- cpumask_clear(tmpmask);
- now = ktime_get();
-@@ -1061,6 +1065,7 @@ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc,
-
-
- bc->event_handler = tick_handle_oneshot_broadcast;
-+ bc->next_event_forced = 0;
- bc->next_event = KTIME_MAX;
-
- /*
-@@ -1173,6 +1178,7 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
- }
-
- /* This moves the broadcast assignment to this CPU: */
-+ bc->next_event_forced = 0;
- clockevents_program_event(bc, bc->next_event, 1);
- }
- raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
-index 9a3859443c042..4b5a42192afa2 100644
---- a/kernel/time/tick-common.c
-+++ b/kernel/time/tick-common.c
-@@ -110,6 +110,7 @@ void tick_handle_periodic(struct clock_event_device *dev)
- int cpu = smp_processor_id();
- ktime_t next = dev->next_event;
-
-+ dev->next_event_forced = 0;
- tick_periodic(cpu);
-
- /*
-diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
-index f203f000da1ad..e385555b456e8 100644
---- a/kernel/time/tick-sched.c
-+++ b/kernel/time/tick-sched.c
-@@ -1488,6 +1488,7 @@ static void tick_nohz_lowres_handler(struct clock_event_device *dev)
- struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
-
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- if (likely(tick_nohz_handler(&ts->sched_timer) == HRTIMER_RESTART))
- tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
---
-2.53.0
-
crypto-af_alg-limit-rx-sg-extraction-by-receive-buff.patch
perf-x86-intel-uncore-skip-discovery-table-for-offli.patch
sched-deadline-use-revised-wakeup-rule-for-dl_server.patch
-clockevents-prevent-timer-interrupt-starvation.patch
crypto-algif_aead-fix-minimum-rx-size-check-for-decr.patch
netfilter-conntrack-add-missing-netlink-policy-valid.patch
revert-drm-xe-mmio-avoid-double-adjust-in-64-bit-rea.patch
+++ /dev/null
-From ff3638ff00c87218340038cfcb28b7446240b4bd Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 7 Apr 2026 10:54:17 +0200
-Subject: clockevents: Prevent timer interrupt starvation
-
-From: Thomas Gleixner <tglx@kernel.org>
-
-[ Upstream commit d6e152d905bdb1f32f9d99775e2f453350399a6a ]
-
-Calvin reported an odd NMI watchdog lockup which claims that the CPU locked
-up in user space. He provided a reproducer, which sets up a timerfd based
-timer and then rearms it in a loop with an absolute expiry time of 1ns.
-
-As the expiry time is in the past, the timer ends up as the first expiring
-timer in the per CPU hrtimer base and the clockevent device is programmed
-with the minimum delta value. If the machine is fast enough, this ends up
-in a endless loop of programming the delta value to the minimum value
-defined by the clock event device, before the timer interrupt can fire,
-which starves the interrupt and consequently triggers the lockup detector
-because the hrtimer callback of the lockup mechanism is never invoked.
-
-As a first step to prevent this, avoid reprogramming the clock event device
-when:
- - a forced minimum delta event is pending
- - the new expiry delta is less then or equal to the minimum delta
-
-Thanks to Calvin for providing the reproducer and to Borislav for testing
-and providing data from his Zen5 machine.
-
-The problem is not limited to Zen5, but depending on the underlying
-clock event device (e.g. TSC deadline timer on Intel) and the CPU speed
-not necessarily observable.
-
-This change serves only as the last resort and further changes will be made
-to prevent this scenario earlier in the call chain as far as possible.
-
-[ tglx: Updated to restore the old behaviour vs. !force and delta <= 0 and
- fixed up the tick-broadcast handlers as pointed out by Borislav ]
-
-Fixes: d316c57ff6bf ("[PATCH] clockevents: add core functionality")
-Reported-by: Calvin Owens <calvin@wbinvd.org>
-Signed-off-by: Thomas Gleixner <tglx@kernel.org>
-Tested-by: Calvin Owens <calvin@wbinvd.org>
-Tested-by: Borislav Petkov <bp@alien8.de>
-Link: https://lore.kernel.org/lkml/acMe-QZUel-bBYUh@mozart.vkv.me/
-Link: https://patch.msgid.link/20260407083247.562657657@kernel.org
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/clockchips.h | 2 ++
- kernel/time/clockevents.c | 27 +++++++++++++++++++--------
- kernel/time/hrtimer.c | 1 +
- kernel/time/tick-broadcast.c | 8 +++++++-
- kernel/time/tick-common.c | 1 +
- kernel/time/tick-sched.c | 1 +
- 6 files changed, 31 insertions(+), 9 deletions(-)
-
-diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
-index b0df28ddd394b..50cdc9da8d32a 100644
---- a/include/linux/clockchips.h
-+++ b/include/linux/clockchips.h
-@@ -80,6 +80,7 @@ enum clock_event_state {
- * @shift: nanoseconds to cycles divisor (power of two)
- * @state_use_accessors:current state of the device, assigned by the core code
- * @features: features
-+ * @next_event_forced: True if the last programming was a forced event
- * @retries: number of forced programming retries
- * @set_state_periodic: switch state to periodic
- * @set_state_oneshot: switch state to oneshot
-@@ -108,6 +109,7 @@ struct clock_event_device {
- u32 shift;
- enum clock_event_state state_use_accessors;
- unsigned int features;
-+ unsigned int next_event_forced;
- unsigned long retries;
-
- int (*set_state_periodic)(struct clock_event_device *);
-diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
-index a59bc75ab7c5b..e7b0163eeeb44 100644
---- a/kernel/time/clockevents.c
-+++ b/kernel/time/clockevents.c
-@@ -172,6 +172,7 @@ void clockevents_shutdown(struct clock_event_device *dev)
- {
- clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
- }
-
- /**
-@@ -305,7 +306,6 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- {
- unsigned long long clc;
- int64_t delta;
-- int rc;
-
- if (WARN_ON_ONCE(expires < 0))
- return -ETIME;
-@@ -324,16 +324,27 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- return dev->set_next_ktime(expires, dev);
-
- delta = ktime_to_ns(ktime_sub(expires, ktime_get()));
-- if (delta <= 0)
-- return force ? clockevents_program_min_delta(dev) : -ETIME;
-
-- delta = min(delta, (int64_t) dev->max_delta_ns);
-- delta = max(delta, (int64_t) dev->min_delta_ns);
-+ /* Required for tick_periodic() during early boot */
-+ if (delta <= 0 && !force)
-+ return -ETIME;
-+
-+ if (delta > (int64_t)dev->min_delta_ns) {
-+ delta = min(delta, (int64_t) dev->max_delta_ns);
-+ clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-+ if (!dev->set_next_event((unsigned long) clc, dev))
-+ return 0;
-+ }
-
-- clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-- rc = dev->set_next_event((unsigned long) clc, dev);
-+ if (dev->next_event_forced)
-+ return 0;
-
-- return (rc && force) ? clockevents_program_min_delta(dev) : rc;
-+ if (dev->set_next_event(dev->min_delta_ticks, dev)) {
-+ if (!force || clockevents_program_min_delta(dev))
-+ return -ETIME;
-+ }
-+ dev->next_event_forced = 1;
-+ return 0;
- }
-
- /*
-diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
-index 21b6d93401480..fde64bfed98fe 100644
---- a/kernel/time/hrtimer.c
-+++ b/kernel/time/hrtimer.c
-@@ -1880,6 +1880,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
- BUG_ON(!cpu_base->hres_active);
- cpu_base->nr_events++;
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- raw_spin_lock_irqsave(&cpu_base->lock, flags);
- entry_time = now = hrtimer_update_base(cpu_base);
-diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
-index 0207868c8b4d2..e411a378db949 100644
---- a/kernel/time/tick-broadcast.c
-+++ b/kernel/time/tick-broadcast.c
-@@ -76,8 +76,10 @@ const struct clock_event_device *tick_get_wakeup_device(int cpu)
- */
- static void tick_broadcast_start_periodic(struct clock_event_device *bc)
- {
-- if (bc)
-+ if (bc) {
-+ bc->next_event_forced = 0;
- tick_setup_periodic(bc, 1);
-+ }
- }
-
- /*
-@@ -403,6 +405,7 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
- bool bc_local;
-
- raw_spin_lock(&tick_broadcast_lock);
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
-
- /* Handle spurious interrupts gracefully */
- if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
-@@ -696,6 +699,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
-
- raw_spin_lock(&tick_broadcast_lock);
- dev->next_event = KTIME_MAX;
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
- next_event = KTIME_MAX;
- cpumask_clear(tmpmask);
- now = ktime_get();
-@@ -1063,6 +1067,7 @@ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc,
-
-
- bc->event_handler = tick_handle_oneshot_broadcast;
-+ bc->next_event_forced = 0;
- bc->next_event = KTIME_MAX;
-
- /*
-@@ -1175,6 +1180,7 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
- }
-
- /* This moves the broadcast assignment to this CPU: */
-+ bc->next_event_forced = 0;
- clockevents_program_event(bc, bc->next_event, 1);
- }
- raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
-index 7e33d3f2e889b..b0c669a7745a7 100644
---- a/kernel/time/tick-common.c
-+++ b/kernel/time/tick-common.c
-@@ -110,6 +110,7 @@ void tick_handle_periodic(struct clock_event_device *dev)
- int cpu = smp_processor_id();
- ktime_t next = dev->next_event;
-
-+ dev->next_event_forced = 0;
- tick_periodic(cpu);
-
- /*
-diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
-index 466e083c82721..36f27a8ae6c03 100644
---- a/kernel/time/tick-sched.c
-+++ b/kernel/time/tick-sched.c
-@@ -1482,6 +1482,7 @@ static void tick_nohz_lowres_handler(struct clock_event_device *dev)
- struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
-
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- if (likely(tick_nohz_handler(&ts->sched_timer) == HRTIMER_RESTART))
- tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
---
-2.53.0
-
crypto-af_alg-limit-rx-sg-extraction-by-receive-buff.patch
perf-x86-intel-uncore-skip-discovery-table-for-offli.patch
sched-deadline-use-revised-wakeup-rule-for-dl_server.patch
-clockevents-prevent-timer-interrupt-starvation.patch
crypto-af_alg-fix-page-reassignment-overflow-in-af_a.patch
crypto-algif_aead-fix-minimum-rx-size-check-for-decr.patch
netfilter-conntrack-add-missing-netlink-policy-valid.patch
+++ /dev/null
-From 8c7a391b93a21a2bbf1e6e8f6e685affdf59b886 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 7 Apr 2026 10:54:17 +0200
-Subject: clockevents: Prevent timer interrupt starvation
-
-From: Thomas Gleixner <tglx@kernel.org>
-
-[ Upstream commit d6e152d905bdb1f32f9d99775e2f453350399a6a ]
-
-Calvin reported an odd NMI watchdog lockup which claims that the CPU locked
-up in user space. He provided a reproducer, which sets up a timerfd based
-timer and then rearms it in a loop with an absolute expiry time of 1ns.
-
-As the expiry time is in the past, the timer ends up as the first expiring
-timer in the per CPU hrtimer base and the clockevent device is programmed
-with the minimum delta value. If the machine is fast enough, this ends up
-in a endless loop of programming the delta value to the minimum value
-defined by the clock event device, before the timer interrupt can fire,
-which starves the interrupt and consequently triggers the lockup detector
-because the hrtimer callback of the lockup mechanism is never invoked.
-
-As a first step to prevent this, avoid reprogramming the clock event device
-when:
- - a forced minimum delta event is pending
- - the new expiry delta is less then or equal to the minimum delta
-
-Thanks to Calvin for providing the reproducer and to Borislav for testing
-and providing data from his Zen5 machine.
-
-The problem is not limited to Zen5, but depending on the underlying
-clock event device (e.g. TSC deadline timer on Intel) and the CPU speed
-not necessarily observable.
-
-This change serves only as the last resort and further changes will be made
-to prevent this scenario earlier in the call chain as far as possible.
-
-[ tglx: Updated to restore the old behaviour vs. !force and delta <= 0 and
- fixed up the tick-broadcast handlers as pointed out by Borislav ]
-
-Fixes: d316c57ff6bf ("[PATCH] clockevents: add core functionality")
-Reported-by: Calvin Owens <calvin@wbinvd.org>
-Signed-off-by: Thomas Gleixner <tglx@kernel.org>
-Tested-by: Calvin Owens <calvin@wbinvd.org>
-Tested-by: Borislav Petkov <bp@alien8.de>
-Link: https://lore.kernel.org/lkml/acMe-QZUel-bBYUh@mozart.vkv.me/
-Link: https://patch.msgid.link/20260407083247.562657657@kernel.org
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/clockchips.h | 2 ++
- kernel/time/clockevents.c | 27 +++++++++++++++++++--------
- kernel/time/hrtimer.c | 1 +
- kernel/time/tick-broadcast.c | 8 +++++++-
- kernel/time/tick-common.c | 1 +
- kernel/time/tick-sched.c | 1 +
- 6 files changed, 31 insertions(+), 9 deletions(-)
-
-diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
-index b0df28ddd394b..50cdc9da8d32a 100644
---- a/include/linux/clockchips.h
-+++ b/include/linux/clockchips.h
-@@ -80,6 +80,7 @@ enum clock_event_state {
- * @shift: nanoseconds to cycles divisor (power of two)
- * @state_use_accessors:current state of the device, assigned by the core code
- * @features: features
-+ * @next_event_forced: True if the last programming was a forced event
- * @retries: number of forced programming retries
- * @set_state_periodic: switch state to periodic
- * @set_state_oneshot: switch state to oneshot
-@@ -108,6 +109,7 @@ struct clock_event_device {
- u32 shift;
- enum clock_event_state state_use_accessors;
- unsigned int features;
-+ unsigned int next_event_forced;
- unsigned long retries;
-
- int (*set_state_periodic)(struct clock_event_device *);
-diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
-index eaae1ce9f0600..38570998a19b8 100644
---- a/kernel/time/clockevents.c
-+++ b/kernel/time/clockevents.c
-@@ -172,6 +172,7 @@ void clockevents_shutdown(struct clock_event_device *dev)
- {
- clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
- }
-
- /**
-@@ -305,7 +306,6 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- {
- unsigned long long clc;
- int64_t delta;
-- int rc;
-
- if (WARN_ON_ONCE(expires < 0))
- return -ETIME;
-@@ -324,16 +324,27 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- return dev->set_next_ktime(expires, dev);
-
- delta = ktime_to_ns(ktime_sub(expires, ktime_get()));
-- if (delta <= 0)
-- return force ? clockevents_program_min_delta(dev) : -ETIME;
-
-- delta = min(delta, (int64_t) dev->max_delta_ns);
-- delta = max(delta, (int64_t) dev->min_delta_ns);
-+ /* Required for tick_periodic() during early boot */
-+ if (delta <= 0 && !force)
-+ return -ETIME;
-+
-+ if (delta > (int64_t)dev->min_delta_ns) {
-+ delta = min(delta, (int64_t) dev->max_delta_ns);
-+ clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-+ if (!dev->set_next_event((unsigned long) clc, dev))
-+ return 0;
-+ }
-
-- clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-- rc = dev->set_next_event((unsigned long) clc, dev);
-+ if (dev->next_event_forced)
-+ return 0;
-
-- return (rc && force) ? clockevents_program_min_delta(dev) : rc;
-+ if (dev->set_next_event(dev->min_delta_ticks, dev)) {
-+ if (!force || clockevents_program_min_delta(dev))
-+ return -ETIME;
-+ }
-+ dev->next_event_forced = 1;
-+ return 0;
- }
-
- /*
-diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
-index 84c8ab2a0cebf..141b2beac63a4 100644
---- a/kernel/time/hrtimer.c
-+++ b/kernel/time/hrtimer.c
-@@ -1880,6 +1880,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
- BUG_ON(!cpu_base->hres_active);
- cpu_base->nr_events++;
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- raw_spin_lock_irqsave(&cpu_base->lock, flags);
- entry_time = now = hrtimer_update_base(cpu_base);
-diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
-index f63c65881364d..7e57fa31ee26f 100644
---- a/kernel/time/tick-broadcast.c
-+++ b/kernel/time/tick-broadcast.c
-@@ -76,8 +76,10 @@ const struct clock_event_device *tick_get_wakeup_device(int cpu)
- */
- static void tick_broadcast_start_periodic(struct clock_event_device *bc)
- {
-- if (bc)
-+ if (bc) {
-+ bc->next_event_forced = 0;
- tick_setup_periodic(bc, 1);
-+ }
- }
-
- /*
-@@ -403,6 +405,7 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
- bool bc_local;
-
- raw_spin_lock(&tick_broadcast_lock);
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
-
- /* Handle spurious interrupts gracefully */
- if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
-@@ -696,6 +699,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
-
- raw_spin_lock(&tick_broadcast_lock);
- dev->next_event = KTIME_MAX;
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
- next_event = KTIME_MAX;
- cpumask_clear(tmpmask);
- now = ktime_get();
-@@ -1063,6 +1067,7 @@ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc,
-
-
- bc->event_handler = tick_handle_oneshot_broadcast;
-+ bc->next_event_forced = 0;
- bc->next_event = KTIME_MAX;
-
- /*
-@@ -1175,6 +1180,7 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
- }
-
- /* This moves the broadcast assignment to this CPU: */
-+ bc->next_event_forced = 0;
- clockevents_program_event(bc, bc->next_event, 1);
- }
- raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
-index d305d85218961..6a9198a4279b5 100644
---- a/kernel/time/tick-common.c
-+++ b/kernel/time/tick-common.c
-@@ -110,6 +110,7 @@ void tick_handle_periodic(struct clock_event_device *dev)
- int cpu = smp_processor_id();
- ktime_t next = dev->next_event;
-
-+ dev->next_event_forced = 0;
- tick_periodic(cpu);
-
- /*
-diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
-index 2f8a7923fa279..6e2f239a4813f 100644
---- a/kernel/time/tick-sched.c
-+++ b/kernel/time/tick-sched.c
-@@ -1504,6 +1504,7 @@ static void tick_nohz_lowres_handler(struct clock_event_device *dev)
- struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
-
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- if (likely(tick_nohz_handler(&ts->sched_timer) == HRTIMER_RESTART))
- tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
---
-2.53.0
-
perf-x86-intel-uncore-skip-discovery-table-for-offli.patch
perf-x86-intel-uncore-fix-die-id-init-and-look-up-bu.patch
sched-deadline-use-revised-wakeup-rule-for-dl_server.patch
-clockevents-prevent-timer-interrupt-starvation.patch
crypto-af_alg-fix-page-reassignment-overflow-in-af_a.patch
crypto-algif_aead-fix-minimum-rx-size-check-for-decr.patch
nfc-llcp-add-missing-return-after-llcp_closed-checks.patch
+++ /dev/null
-From 051fea00173d929d0ed32c7ffa323fbe431d8242 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 7 Apr 2026 10:54:17 +0200
-Subject: clockevents: Prevent timer interrupt starvation
-
-From: Thomas Gleixner <tglx@kernel.org>
-
-[ Upstream commit d6e152d905bdb1f32f9d99775e2f453350399a6a ]
-
-Calvin reported an odd NMI watchdog lockup which claims that the CPU locked
-up in user space. He provided a reproducer, which sets up a timerfd based
-timer and then rearms it in a loop with an absolute expiry time of 1ns.
-
-As the expiry time is in the past, the timer ends up as the first expiring
-timer in the per CPU hrtimer base and the clockevent device is programmed
-with the minimum delta value. If the machine is fast enough, this ends up
-in a endless loop of programming the delta value to the minimum value
-defined by the clock event device, before the timer interrupt can fire,
-which starves the interrupt and consequently triggers the lockup detector
-because the hrtimer callback of the lockup mechanism is never invoked.
-
-As a first step to prevent this, avoid reprogramming the clock event device
-when:
- - a forced minimum delta event is pending
- - the new expiry delta is less then or equal to the minimum delta
-
-Thanks to Calvin for providing the reproducer and to Borislav for testing
-and providing data from his Zen5 machine.
-
-The problem is not limited to Zen5, but depending on the underlying
-clock event device (e.g. TSC deadline timer on Intel) and the CPU speed
-not necessarily observable.
-
-This change serves only as the last resort and further changes will be made
-to prevent this scenario earlier in the call chain as far as possible.
-
-[ tglx: Updated to restore the old behaviour vs. !force and delta <= 0 and
- fixed up the tick-broadcast handlers as pointed out by Borislav ]
-
-Fixes: d316c57ff6bf ("[PATCH] clockevents: add core functionality")
-Reported-by: Calvin Owens <calvin@wbinvd.org>
-Signed-off-by: Thomas Gleixner <tglx@kernel.org>
-Tested-by: Calvin Owens <calvin@wbinvd.org>
-Tested-by: Borislav Petkov <bp@alien8.de>
-Link: https://lore.kernel.org/lkml/acMe-QZUel-bBYUh@mozart.vkv.me/
-Link: https://patch.msgid.link/20260407083247.562657657@kernel.org
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/clockchips.h | 2 ++
- kernel/time/clockevents.c | 27 +++++++++++++++++++--------
- kernel/time/hrtimer.c | 1 +
- kernel/time/tick-broadcast.c | 8 +++++++-
- kernel/time/tick-common.c | 1 +
- kernel/time/tick-sched.c | 1 +
- 6 files changed, 31 insertions(+), 9 deletions(-)
-
-diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
-index 9aac31d856f39..c0d767b8f4bd5 100644
---- a/include/linux/clockchips.h
-+++ b/include/linux/clockchips.h
-@@ -80,6 +80,7 @@ enum clock_event_state {
- * @shift: nanoseconds to cycles divisor (power of two)
- * @state_use_accessors:current state of the device, assigned by the core code
- * @features: features
-+ * @next_event_forced: True if the last programming was a forced event
- * @retries: number of forced programming retries
- * @set_state_periodic: switch state to periodic
- * @set_state_oneshot: switch state to oneshot
-@@ -108,6 +109,7 @@ struct clock_event_device {
- u32 shift;
- enum clock_event_state state_use_accessors;
- unsigned int features;
-+ unsigned int next_event_forced;
- unsigned long retries;
-
- int (*set_state_periodic)(struct clock_event_device *);
-diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
-index 960143b183cdb..0869b3902605e 100644
---- a/kernel/time/clockevents.c
-+++ b/kernel/time/clockevents.c
-@@ -172,6 +172,7 @@ void clockevents_shutdown(struct clock_event_device *dev)
- {
- clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
- }
-
- /**
-@@ -305,7 +306,6 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- {
- unsigned long long clc;
- int64_t delta;
-- int rc;
-
- if (WARN_ON_ONCE(expires < 0))
- return -ETIME;
-@@ -324,16 +324,27 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
- return dev->set_next_ktime(expires, dev);
-
- delta = ktime_to_ns(ktime_sub(expires, ktime_get()));
-- if (delta <= 0)
-- return force ? clockevents_program_min_delta(dev) : -ETIME;
-
-- delta = min(delta, (int64_t) dev->max_delta_ns);
-- delta = max(delta, (int64_t) dev->min_delta_ns);
-+ /* Required for tick_periodic() during early boot */
-+ if (delta <= 0 && !force)
-+ return -ETIME;
-+
-+ if (delta > (int64_t)dev->min_delta_ns) {
-+ delta = min(delta, (int64_t) dev->max_delta_ns);
-+ clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-+ if (!dev->set_next_event((unsigned long) clc, dev))
-+ return 0;
-+ }
-
-- clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-- rc = dev->set_next_event((unsigned long) clc, dev);
-+ if (dev->next_event_forced)
-+ return 0;
-
-- return (rc && force) ? clockevents_program_min_delta(dev) : rc;
-+ if (dev->set_next_event(dev->min_delta_ticks, dev)) {
-+ if (!force || clockevents_program_min_delta(dev))
-+ return -ETIME;
-+ }
-+ dev->next_event_forced = 1;
-+ return 0;
- }
-
- /*
-diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
-index 03f488f93cddf..9a8a2d36b9db6 100644
---- a/kernel/time/hrtimer.c
-+++ b/kernel/time/hrtimer.c
-@@ -1853,6 +1853,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
- BUG_ON(!cpu_base->hres_active);
- cpu_base->nr_events++;
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- raw_spin_lock_irqsave(&cpu_base->lock, flags);
- entry_time = now = hrtimer_update_base(cpu_base);
-diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
-index ed58eebb4e8f4..99d2978ef9b98 100644
---- a/kernel/time/tick-broadcast.c
-+++ b/kernel/time/tick-broadcast.c
-@@ -76,8 +76,10 @@ const struct clock_event_device *tick_get_wakeup_device(int cpu)
- */
- static void tick_broadcast_start_periodic(struct clock_event_device *bc)
- {
-- if (bc)
-+ if (bc) {
-+ bc->next_event_forced = 0;
- tick_setup_periodic(bc, 1);
-+ }
- }
-
- /*
-@@ -403,6 +405,7 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
- bool bc_local;
-
- raw_spin_lock(&tick_broadcast_lock);
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
-
- /* Handle spurious interrupts gracefully */
- if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
-@@ -696,6 +699,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
-
- raw_spin_lock(&tick_broadcast_lock);
- dev->next_event = KTIME_MAX;
-+ tick_broadcast_device.evtdev->next_event_forced = 0;
- next_event = KTIME_MAX;
- cpumask_clear(tmpmask);
- now = ktime_get();
-@@ -1061,6 +1065,7 @@ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc,
-
-
- bc->event_handler = tick_handle_oneshot_broadcast;
-+ bc->next_event_forced = 0;
- bc->next_event = KTIME_MAX;
-
- /*
-@@ -1173,6 +1178,7 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
- }
-
- /* This moves the broadcast assignment to this CPU: */
-+ bc->next_event_forced = 0;
- clockevents_program_event(bc, bc->next_event, 1);
- }
- raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
-diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
-index ecdb8c2b2cab2..d5c9af9c6c333 100644
---- a/kernel/time/tick-common.c
-+++ b/kernel/time/tick-common.c
-@@ -109,6 +109,7 @@ void tick_handle_periodic(struct clock_event_device *dev)
- int cpu = smp_processor_id();
- ktime_t next = dev->next_event;
-
-+ dev->next_event_forced = 0;
- tick_periodic(cpu);
-
- #if defined(CONFIG_HIGH_RES_TIMERS) || defined(CONFIG_NO_HZ_COMMON)
-diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
-index 55cbc49f70d14..bf3ff0dbf2a28 100644
---- a/kernel/time/tick-sched.c
-+++ b/kernel/time/tick-sched.c
-@@ -1373,6 +1373,7 @@ static void tick_nohz_handler(struct clock_event_device *dev)
- ktime_t now = ktime_get();
-
- dev->next_event = KTIME_MAX;
-+ dev->next_event_forced = 0;
-
- tick_sched_do_timer(ts, now);
- tick_sched_handle(ts, regs);
---
-2.53.0
-
l2tp-drop-large-packets-with-udp-encap.patch
gpio-tegra-fix-irq_release_resources-calling-enable-.patch
perf-x86-intel-uncore-skip-discovery-table-for-offli.patch
-clockevents-prevent-timer-interrupt-starvation.patch
crypto-algif_aead-fix-minimum-rx-size-check-for-decr.patch
netfilter-conntrack-add-missing-netlink-policy-valid.patch
alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch