aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-03-15 13:17:38 +0000
committerKeir Fraser <keir.fraser@citrix.com>2010-03-15 13:17:38 +0000
commit55120309eda0d3bfab572c78b187d57f68054d58 (patch)
tree4533667657c17c564ee17f443379e8bfed5bd979
parentf1ad4b4ad79e5c3db55fc12826ab19983b03b2e7 (diff)
downloadxen-55120309eda0d3bfab572c78b187d57f68054d58.tar.gz
xen-55120309eda0d3bfab572c78b187d57f68054d58.tar.bz2
xen-55120309eda0d3bfab572c78b187d57f68054d58.zip
x86: Fix possible S3 suspend hangs
It is possible for cpu to become offlined before irq disabled in idle loop, which will cause this cpu stay in C state and can't wakeup to play dead. Signed-off-by: Wei Gang <gang.wei@intel.com> Signed-off-by: Yu Ke <ke.yu@intel.com>
-rw-r--r--xen/arch/x86/acpi/cpu_idle.c3
-rw-r--r--xen/arch/x86/domain.c3
2 files changed, 4 insertions, 2 deletions
diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index f06580fbb4..51227842e4 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -268,7 +268,8 @@ static void acpi_processor_idle(void)
*/
local_irq_disable();
- if ( softirq_pending(smp_processor_id()) )
+ if ( softirq_pending(smp_processor_id()) ||
+ cpu_is_offline(smp_processor_id()) )
{
local_irq_enable();
sched_tick_resume();
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index d20487f8d9..17f5c83c75 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -82,7 +82,8 @@ static void continue_nonidle_domain(struct vcpu *v)
static void default_idle(void)
{
local_irq_disable();
- if ( !softirq_pending(smp_processor_id()) )
+ if ( !softirq_pending(smp_processor_id()) &&
+ cpu_online(smp_processor_id()) )
safe_halt();
else
local_irq_enable();