diff options
-rw-r--r-- | arch/powerpc/kernel/crash.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index cca7c8fafc1c..8c066d6a8e4b 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -162,6 +162,32 @@ static void crash_kexec_prepare_cpus(int cpu) | |||
162 | /* Leave the IPI callback set */ | 162 | /* Leave the IPI callback set */ |
163 | } | 163 | } |
164 | 164 | ||
165 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ | ||
166 | static void crash_kexec_wait_realmode(int cpu) | ||
167 | { | ||
168 | unsigned int msecs; | ||
169 | int i; | ||
170 | |||
171 | msecs = 10000; | ||
172 | for (i=0; i < NR_CPUS && msecs > 0; i++) { | ||
173 | if (i == cpu) | ||
174 | continue; | ||
175 | |||
176 | while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { | ||
177 | barrier(); | ||
178 | if (!cpu_possible(i)) { | ||
179 | break; | ||
180 | } | ||
181 | if (!cpu_online(i)) { | ||
182 | break; | ||
183 | } | ||
184 | msecs--; | ||
185 | mdelay(1); | ||
186 | } | ||
187 | } | ||
188 | mb(); | ||
189 | } | ||
190 | |||
165 | /* | 191 | /* |
166 | * This function will be called by secondary cpus or by kexec cpu | 192 | * This function will be called by secondary cpus or by kexec cpu |
167 | * if soft-reset is activated to stop some CPUs. | 193 | * if soft-reset is activated to stop some CPUs. |
@@ -419,6 +445,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
419 | crash_kexec_prepare_cpus(crashing_cpu); | 445 | crash_kexec_prepare_cpus(crashing_cpu); |
420 | cpu_set(crashing_cpu, cpus_in_crash); | 446 | cpu_set(crashing_cpu, cpus_in_crash); |
421 | crash_kexec_stop_spus(); | 447 | crash_kexec_stop_spus(); |
448 | crash_kexec_wait_realmode(crashing_cpu); | ||
422 | if (ppc_md.kexec_cpu_down) | 449 | if (ppc_md.kexec_cpu_down) |
423 | ppc_md.kexec_cpu_down(1, 0); | 450 | ppc_md.kexec_cpu_down(1, 0); |
424 | } | 451 | } |