diff options
Diffstat (limited to 'arch/x86/kernel/smp.c')
| -rw-r--r-- | arch/x86/kernel/smp.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 28f5fb495a66..ec1de97600e7 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
| @@ -150,14 +150,40 @@ void native_send_call_func_ipi(const struct cpumask *mask) | |||
| 150 | * this function calls the 'stop' function on all other CPUs in the system. | 150 | * this function calls the 'stop' function on all other CPUs in the system. |
| 151 | */ | 151 | */ |
| 152 | 152 | ||
| 153 | asmlinkage void smp_reboot_interrupt(void) | ||
| 154 | { | ||
| 155 | ack_APIC_irq(); | ||
| 156 | irq_enter(); | ||
| 157 | stop_this_cpu(NULL); | ||
| 158 | irq_exit(); | ||
| 159 | } | ||
| 160 | |||
| 153 | static void native_smp_send_stop(void) | 161 | static void native_smp_send_stop(void) |
| 154 | { | 162 | { |
| 155 | unsigned long flags; | 163 | unsigned long flags; |
| 164 | unsigned long wait; | ||
| 156 | 165 | ||
| 157 | if (reboot_force) | 166 | if (reboot_force) |
| 158 | return; | 167 | return; |
| 159 | 168 | ||
| 160 | smp_call_function(stop_this_cpu, NULL, 0); | 169 | /* |
| 170 | * Use an own vector here because smp_call_function | ||
| 171 | * does lots of things not suitable in a panic situation. | ||
| 172 | * On most systems we could also use an NMI here, | ||
| 173 | * but there are a few systems around where NMI | ||
| 174 | * is problematic so stay with an non NMI for now | ||
| 175 | * (this implies we cannot stop CPUs spinning with irq off | ||
| 176 | * currently) | ||
| 177 | */ | ||
| 178 | if (num_online_cpus() > 1) { | ||
| 179 | apic->send_IPI_allbutself(REBOOT_VECTOR); | ||
| 180 | |||
| 181 | /* Don't wait longer than a second */ | ||
| 182 | wait = USEC_PER_SEC; | ||
| 183 | while (num_online_cpus() > 1 && wait--) | ||
| 184 | udelay(1); | ||
| 185 | } | ||
| 186 | |||
| 161 | local_irq_save(flags); | 187 | local_irq_save(flags); |
| 162 | disable_local_APIC(); | 188 | disable_local_APIC(); |
| 163 | local_irq_restore(flags); | 189 | local_irq_restore(flags); |
