Thread (5 messages) 5 messages, 2 authors, 6d ago

Re: [PATCH v3 3/3] powerpc/kexec: fix double get_cpu() imbalance in kexec_prepare_cpus

From: Shrikanth Hegde <hidden>
Date: 2026-06-05 11:03:30
Also in: lkml


On 6/5/26 1:59 PM, Aboorva Devarajan wrote:
quoted hunk ↗ jump to hunk
kexec_prepare_cpus_wait() calls get_cpu() internally to obtain the
current CPU id. kexec_prepare_cpus() calls kexec_prepare_cpus_wait()
twice -- once for KEXEC_STATE_IRQS_OFF and once for
KEXEC_STATE_REAL_MODE -- but only issues a single put_cpu() at the end,
leaving preempt_count elevated by one extra nesting level.

In practice the imbalance does not trigger a 'scheduling while atomic'
splat because the kexec path is a one-way trip: IRQs are already
disabled, no schedule() occurs after the leak, and
default_machine_kexec() overwrites preempt_count with HARDIRQ_OFFSET
before jumping into kexec_sequence() which never returns. However the
bookkeeping is still wrong.

kexec_prepare_cpus() calls local_irq_disable()/hard_irq_disable()
before invoking kexec_prepare_cpus_wait(), so the CPU is already pinned
and the get_cpu()/put_cpu() preempt_disable() bracketing is unnecessary.
Only the current CPU id is needed, so replace get_cpu() with
raw_smp_processor_id() and drop the now-unneeded put_cpu().

Fixes: 1fc711f7ffb0 ("powerpc/kexec: Fix race in kexec shutdown")
Signed-off-by: Aboorva Devarajan <redacted>
---
  arch/powerpc/kexec/core_64.c | 4 +---
  1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
index 825ab8a88f18..58c13a59b93b 100644
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -169,7 +169,7 @@ static void kexec_prepare_cpus_wait(int wait_state)
  	int my_cpu, i, notified=-1;
  
  	hw_breakpoint_disable();
-	my_cpu = get_cpu();
+	my_cpu = raw_smp_processor_id();
  	/* Make sure each CPU has at least made it to the state we need.
  	 *
  	 * FIXME: There is a (slim) chance of a problem if not all of the CPUs
@@ -267,8 +267,6 @@ static void kexec_prepare_cpus(void)
  	/* after we tell the others to go down */
  	if (ppc_md.kexec_cpu_down)
  		ppc_md.kexec_cpu_down(0, 0);
-
-	put_cpu();
  }
  
  #else /* ! SMP */

Reviewed-by: Shrikanth Hegde <redacted>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help