54 lines
1.6 KiB
Diff
54 lines
1.6 KiB
Diff
|
# HG changeset patch
|
||
|
# User Ben Guthro <ben@guthro.net>
|
||
|
# Date 1348555094 -7200
|
||
|
# Node ID c8d65d91a6f20fa7fae905bbf172e59b335d6371
|
||
|
# Parent b49f7bf52fa92626517386cba89350243b808871
|
||
|
x86/S3: add cache flush on secondary CPUs before going to sleep
|
||
|
|
||
|
Secondary CPUs, between doing their final memory writes (particularly
|
||
|
updating cpu_initialized) and getting a subsequent INIT, may not write
|
||
|
back all modified data. The INIT itself then causes those modifications
|
||
|
to be lost, so in the cpu_initialized case the CPU would find itself
|
||
|
already initialized, (intentionally) entering an infinite loop instead
|
||
|
of actually coming online.
|
||
|
|
||
|
Signed-off-by: Ben Guthro <ben@guthro.net>
|
||
|
|
||
|
Make acpi_dead_idle() call default_dead_idle() rather than duplicating
|
||
|
the logic there.
|
||
|
|
||
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||
|
Acked-by: Keir Fraser <keir@xen.org>
|
||
|
Committed-by: Jan Beulich <jbeulich@suse.com>
|
||
|
|
||
|
--- a/xen/arch/x86/acpi/cpu_idle.c
|
||
|
+++ b/xen/arch/x86/acpi/cpu_idle.c
|
||
|
@@ -647,6 +647,12 @@ static void acpi_dead_idle(void)
|
||
|
}
|
||
|
|
||
|
default_halt:
|
||
|
+ /*
|
||
|
+ * When going into S3, without flushing caches modified data may be
|
||
|
+ * held by the CPUs spinning here indefinitely, and get discarded by
|
||
|
+ * a subsequent INIT.
|
||
|
+ */
|
||
|
+ wbinvd();
|
||
|
for ( ; ; )
|
||
|
halt();
|
||
|
}
|
||
|
--- a/xen/arch/x86/domain.c
|
||
|
+++ b/xen/arch/x86/domain.c
|
||
|
@@ -86,6 +86,12 @@ static void default_idle(void)
|
||
|
|
||
|
static void default_dead_idle(void)
|
||
|
{
|
||
|
+ /*
|
||
|
+ * When going into S3, without flushing caches modified data may be
|
||
|
+ * held by the CPUs spinning here indefinitely, and get discarded by
|
||
|
+ * a subsequent INIT.
|
||
|
+ */
|
||
|
+ wbinvd();
|
||
|
for ( ; ; )
|
||
|
halt();
|
||
|
}
|