--- /dev/null
+From 2f8dea1692eef2b7ba6a256246ed82c365fdc686 Mon Sep 17 00:00:00 2001
+From: Koichiro Den <koichiro.den@canonical.com>
+Date: Fri, 20 Dec 2024 22:44:21 +0900
+Subject: hrtimers: Handle CPU state correctly on hotplug
+
+From: Koichiro Den <koichiro.den@canonical.com>
+
+commit 2f8dea1692eef2b7ba6a256246ed82c365fdc686 upstream.
+
+Consider a scenario where a CPU transitions from CPUHP_ONLINE to halfway
+through a CPU hotunplug down to CPUHP_HRTIMERS_PREPARE, and then back to
+CPUHP_ONLINE:
+
+Since hrtimers_prepare_cpu() does not run, cpu_base.hres_active remains set
+to 1 throughout. However, during a CPU unplug operation, the tick and the
+clockevents are shut down at CPUHP_AP_TICK_DYING. On return to the online
+state, for instance CFS incorrectly assumes that the hrtick is already
+active, and the chance of the clockevent device to transition to oneshot
+mode is also lost forever for the CPU, unless it goes back to a lower state
+than CPUHP_HRTIMERS_PREPARE once.
+
+This round-trip reveals another issue; cpu_base.online is not set to 1
+after the transition, which appears as a WARN_ON_ONCE in enqueue_hrtimer().
+
+Aside of that, the bulk of the per CPU state is not reset either, which
+means there are dangling pointers in the worst case.
+
+Address this by adding a corresponding startup() callback, which resets the
+stale per CPU state and sets the online flag.
+
+[ tglx: Make the new callback unconditionally available, remove the online
+ modification in the prepare() callback and clear the remaining
+ state in the starting callback instead of the prepare callback ]
+
+Fixes: 5c0930ccaad5 ("hrtimers: Push pending hrtimers away from outgoing CPU earlier")
+Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20241220134421.3809834-1-koichiro.den@canonical.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/hrtimer.h | 1 +
+ kernel/cpu.c | 2 +-
+ kernel/time/hrtimer.c | 11 ++++++++++-
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+--- a/include/linux/hrtimer.h
++++ b/include/linux/hrtimer.h
+@@ -527,6 +527,7 @@ extern void __init hrtimers_init(void);
+ extern void sysrq_timer_list_show(void);
+
+ int hrtimers_prepare_cpu(unsigned int cpu);
++int hrtimers_cpu_starting(unsigned int cpu);
+ #ifdef CONFIG_HOTPLUG_CPU
+ int hrtimers_cpu_dying(unsigned int cpu);
+ #else
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -1542,7 +1542,7 @@ static struct cpuhp_step cpuhp_hp_states
+ },
+ [CPUHP_AP_HRTIMERS_DYING] = {
+ .name = "hrtimers:dying",
+- .startup.single = NULL,
++ .startup.single = hrtimers_cpu_starting,
+ .teardown.single = hrtimers_cpu_dying,
+ },
+
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -2065,6 +2065,15 @@ int hrtimers_prepare_cpu(unsigned int cp
+ }
+
+ cpu_base->cpu = cpu;
++ hrtimer_cpu_base_init_expiry_lock(cpu_base);
++ return 0;
++}
++
++int hrtimers_cpu_starting(unsigned int cpu)
++{
++ struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
++
++ /* Clear out any left over state from a CPU down operation */
+ cpu_base->active_bases = 0;
+ cpu_base->hres_active = 0;
+ cpu_base->hang_detected = 0;
+@@ -2073,7 +2082,6 @@ int hrtimers_prepare_cpu(unsigned int cp
+ cpu_base->expires_next = KTIME_MAX;
+ cpu_base->softirq_expires_next = KTIME_MAX;
+ cpu_base->online = 1;
+- hrtimer_cpu_base_init_expiry_lock(cpu_base);
+ return 0;
+ }
+
+@@ -2151,6 +2159,7 @@ int hrtimers_cpu_dying(unsigned int dyin
+ void __init hrtimers_init(void)
+ {
+ hrtimers_prepare_cpu(smp_processor_id());
++ hrtimers_cpu_starting(smp_processor_id());
+ open_softirq(HRTIMER_SOFTIRQ, hrtimer_run_softirq);
+ }
+
--- /dev/null
+From 0d62a49ab55c99e8deb4593b8d9f923de1ab5c18 Mon Sep 17 00:00:00 2001
+From: Yogesh Lal <quic_ylal@quicinc.com>
+Date: Fri, 20 Dec 2024 15:09:07 +0530
+Subject: irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly
+
+From: Yogesh Lal <quic_ylal@quicinc.com>
+
+commit 0d62a49ab55c99e8deb4593b8d9f923de1ab5c18 upstream.
+
+When a CPU attempts to enter low power mode, it disables the redistributor
+and Group 1 interrupts and reinitializes the system registers upon wakeup.
+
+If the transition into low power mode fails, then the CPU_PM framework
+invokes the PM notifier callback with CPU_PM_ENTER_FAILED to allow the
+drivers to undo the state changes.
+
+The GIC V3 driver ignores CPU_PM_ENTER_FAILED, which leaves the GIC in
+disabled state.
+
+Handle CPU_PM_ENTER_FAILED in the same way as CPU_PM_EXIT to restore normal
+operation.
+
+[ tglx: Massage change log, add Fixes tag ]
+
+Fixes: 3708d52fc6bb ("irqchip: gic-v3: Implement CPU PM notifier")
+Signed-off-by: Yogesh Lal <quic_ylal@quicinc.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20241220093907.2747601-1-quic_ylal@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/irqchip/irq-gic-v3.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/irqchip/irq-gic-v3.c
++++ b/drivers/irqchip/irq-gic-v3.c
+@@ -1185,7 +1185,7 @@ static int gic_set_affinity(struct irq_d
+ static int gic_cpu_pm_notifier(struct notifier_block *self,
+ unsigned long cmd, void *v)
+ {
+- if (cmd == CPU_PM_EXIT) {
++ if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) {
+ if (gic_dist_security_disabled())
+ gic_enable_redist(true);
+ gic_cpu_sys_reg_init();