{
return !cpumask_empty(&cpus_in_xmon);
}
-#endif
+
+static bool wait_for_other_cpus(int ncpus)
+{
+ unsigned long timeout;
+
+ /* We wait for 2s, which is a metric "little while" */
+ for (timeout = 20000; timeout != 0; --timeout) {
+ if (cpumask_weight(&cpus_in_xmon) >= ncpus)
+ return true;
+ udelay(100);
+ barrier();
+ }
+
+ return false;
+}
+#endif /* CONFIG_SMP */
static inline int unrecoverable_excp(struct pt_regs *regs)
{
#ifdef CONFIG_SMP
int cpu;
int secondary;
- unsigned long timeout;
#endif
local_irq_save(flags);
xmon_owner = cpu;
mb();
if (ncpus > 1) {
- smp_send_debugger_break();
- /* wait for other cpus to come in */
- for (timeout = 100000000; timeout != 0; --timeout) {
- if (cpumask_weight(&cpus_in_xmon) >= ncpus)
- break;
- barrier();
- }
+ /*
+ * A system reset (trap == 0x100) can be triggered on
+ * all CPUs, so when we come in via 0x100 try waiting
+ * for the other CPUs to come in before we send the
+ * debugger break (IPI). This is similar to
+ * crash_kexec_secondary().
+ */
+ if (TRAP(regs) != 0x100 || !wait_for_other_cpus(ncpus))
+ smp_send_debugger_break();
+
+ wait_for_other_cpus(ncpus);
}
remove_bpts();
disable_surveillance();