mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
powerpc/kexec: fix double get_cpu() imbalance in kexec_prepare_cpus
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: 1fc711f7ff ("powerpc/kexec: Fix race in kexec shutdown")
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260605082912.305100-4-aboorvad@linux.ibm.com
This commit is contained in:
parent
0ecd26e93e
commit
5c86f1c1f9
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user