aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/smp.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-03-04 10:33:50 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-03-04 10:33:50 +0000
commit53a82fd949458b65af022a4d3a882db181bc36a3 (patch)
tree4a5be81a9bed138ccf97b86711ec87bbb14014ca /xen/arch/x86/smp.c
parent64e04a18cdf4fc2dc9488fe77557bcb4bc285210 (diff)
downloadxen-53a82fd949458b65af022a4d3a882db181bc36a3.tar.gz
xen-53a82fd949458b65af022a4d3a882db181bc36a3.tar.bz2
xen-53a82fd949458b65af022a4d3a882db181bc36a3.zip
x86: On CPU shutdown, clear pending FPU exceptions.
I've seen at least one BIOS which fails warm reboot if FPU exceptions are pending. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/arch/x86/smp.c')
-rw-r--r--xen/arch/x86/smp.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c
index 11e150e75a..51f0688f7c 100644
--- a/xen/arch/x86/smp.c
+++ b/xen/arch/x86/smp.c
@@ -306,15 +306,26 @@ int on_selected_cpus(
return 0;
}
-static void stop_this_cpu (void *dummy)
+static void __stop_this_cpu(void)
{
ASSERT(!local_irq_is_enabled());
disable_local_APIC();
+
hvm_cpu_down();
- cpu_clear(smp_processor_id(), cpu_online_map);
+ /*
+ * Clear FPU, zapping any pending exceptions. Needed for warm reset with
+ * some BIOSes.
+ */
+ clts();
+ asm volatile ( "fninit" );
+}
+static void stop_this_cpu(void *dummy)
+{
+ __stop_this_cpu();
+ cpu_clear(smp_processor_id(), cpu_online_map);
for ( ; ; )
halt();
}
@@ -334,9 +345,8 @@ void smp_send_stop(void)
mdelay(1);
local_irq_disable();
- disable_local_APIC();
+ __stop_this_cpu();
disable_IO_APIC();
- hvm_cpu_down();
local_irq_enable();
}