aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2012-03-23 14:01:05 +0000
committerKeir Fraser <keir@xen.org>2012-03-23 14:01:05 +0000
commitb1a874d21701a48d9f8619578320f2311538dc31 (patch)
tree0403f3f3f0f79b1c03262c0906035089ab81d0aa
parent739fe96a37ec9007e660e24585788ac547c2e77b (diff)
downloadxen-b1a874d21701a48d9f8619578320f2311538dc31.tar.gz
xen-b1a874d21701a48d9f8619578320f2311538dc31.tar.bz2
xen-b1a874d21701a48d9f8619578320f2311538dc31.zip
Introduce system_state variable.
Use it to replace x86-specific early_boot boolean variable. Also use it to detect suspend/resume case during cpu offline/online to avoid unnecessarily breaking vcpu and cpupool affinities. Signed-off-by: Keir Fraser <keir@xen.org> Acked-by: Juergen Gross <juergen.gross@ts.fujitsu.com> xen-unstable changeset: 25079:d5ccb2d1dbd1 xen-unstable date: Thu Mar 22 12:20:13 2012 +0000 Backport requested by Juergen to fix crash on poweroff when using cpupools.
-rw-r--r--xen/arch/x86/acpi/power.c10
-rw-r--r--xen/arch/x86/mm.c2
-rw-r--r--xen/arch/x86/setup.c8
-rw-r--r--xen/arch/x86/x86_32/mm.c2
-rw-r--r--xen/arch/x86/x86_64/mm.c2
-rw-r--r--xen/common/cpupool.c5
-rw-r--r--xen/common/kernel.c2
-rw-r--r--xen/common/schedule.c2
-rw-r--r--xen/include/asm-x86/setup.h1
-rw-r--r--xen/include/xen/kernel.h8
10 files changed, 33 insertions, 9 deletions
diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
index 935c9a1101..53b5e17c44 100644
--- a/xen/arch/x86/acpi/power.c
+++ b/xen/arch/x86/acpi/power.c
@@ -135,6 +135,9 @@ static int enter_state(u32 state)
if ( !spin_trylock(&pm_lock) )
return -EBUSY;
+ BUG_ON(system_state != SYS_STATE_active);
+ system_state = SYS_STATE_suspend;
+
printk(XENLOG_INFO "Preparing system for ACPI S%d state.\n", state);
freeze_domains();
@@ -142,7 +145,10 @@ static int enter_state(u32 state)
acpi_dmar_reinstate();
if ( (error = disable_nonboot_cpus()) )
+ {
+ system_state = SYS_STATE_resume;
goto enable_cpu;
+ }
cpufreq_del_cpu(0);
@@ -159,6 +165,7 @@ static int enter_state(u32 state)
if ( (error = device_power_down()) )
{
printk(XENLOG_ERR "Some devices failed to power down.");
+ system_state = SYS_STATE_resume;
goto done;
}
@@ -179,6 +186,8 @@ static int enter_state(u32 state)
break;
}
+ system_state = SYS_STATE_resume;
+
/* Restore CR4 and EFER from cached values. */
cr4 = read_cr4();
write_cr4(cr4 & ~X86_CR4_MCE);
@@ -212,6 +221,7 @@ static int enter_state(u32 state)
mtrr_aps_sync_end();
acpi_dmar_zap();
thaw_domains();
+ system_state = SYS_STATE_active;
spin_unlock(&pm_lock);
return error;
}
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index fd37a6aa7e..cbdf065909 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5123,7 +5123,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr,
void free_xen_pagetable(void *v)
{
- if ( early_boot )
+ if ( system_state == SYS_STATE_early_boot )
return;
if ( is_xen_heap_page(virt_to_page(v)) )
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 1777ffec51..d88884e4cb 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -87,8 +87,6 @@ boolean_param("noapic", skip_ioapic_setup);
s8 __read_mostly xen_cpuidle = -1;
boolean_param("cpuidle", xen_cpuidle);
-bool_t __read_mostly early_boot = 1;
-
cpumask_t __read_mostly cpu_present_map;
unsigned long __read_mostly xen_phys_start;
@@ -275,7 +273,7 @@ static void *__init bootstrap_map(const module_t *mod)
void *ret;
#ifdef __x86_64__
- if ( !early_boot )
+ if ( system_state != SYS_STATE_early_boot )
return mod ? mfn_to_virt(mod->mod_start) : NULL;
#endif
@@ -1142,7 +1140,7 @@ void __init __start_xen(unsigned long mbi_p)
#endif
end_boot_allocator();
- early_boot = 0;
+ system_state = SYS_STATE_boot;
#if defined(CONFIG_X86_64)
vesa_init();
@@ -1341,6 +1339,8 @@ void __init __start_xen(unsigned long mbi_p)
/* Hide UART from DOM0 if we're using it */
serial_endboot();
+ system_state = SYS_STATE_active;
+
domain_unpause_by_systemcontroller(dom0);
reset_stack_and_jump(init_done);
diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c
index 73a2a9bcbc..16ae743462 100644
--- a/xen/arch/x86/x86_32/mm.c
+++ b/xen/arch/x86/x86_32/mm.c
@@ -45,7 +45,7 @@ void *alloc_xen_pagetable(void)
{
unsigned long mfn;
- if ( !early_boot )
+ if ( system_state != SYS_STATE_early_boot )
{
void *v = alloc_xenheap_page();
diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
index 46c55080bc..72cbca4cfd 100644
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -81,7 +81,7 @@ void *alloc_xen_pagetable(void)
{
unsigned long mfn;
- if ( !early_boot )
+ if ( system_state != SYS_STATE_early_boot )
{
struct page_info *pg = alloc_domheap_page(NULL, 0);
diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c
index c705475538..cafb4be792 100644
--- a/xen/common/cpupool.c
+++ b/xen/common/cpupool.c
@@ -616,6 +616,10 @@ static int cpu_callback(
unsigned int cpu = (unsigned long)hcpu;
int rc = 0;
+ if ( (system_state == SYS_STATE_suspend) ||
+ (system_state == SYS_STATE_resume) )
+ goto out;
+
switch ( action )
{
case CPU_DOWN_FAILED:
@@ -629,6 +633,7 @@ static int cpu_callback(
break;
}
+out:
return !rc ? NOTIFY_DONE : notifier_from_errno(rc);
}
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index c061a0d838..3ce1dcc7a9 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -22,6 +22,8 @@
#ifndef COMPAT
+enum system_state system_state = SYS_STATE_early_boot;
+
int tainted;
xen_commandline_t saved_cmdline;
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 907ea09a76..1ed1bbb4ad 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -546,7 +546,7 @@ int cpu_disable_scheduler(unsigned int cpu)
bool_t affinity_broken;
c = per_cpu(cpupool, cpu);
- if ( c == NULL )
+ if ( (c == NULL) || (system_state == SYS_STATE_suspend) )
return ret;
for_each_domain ( d )
diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h
index 4d1ce7202f..58199476f8 100644
--- a/xen/include/asm-x86/setup.h
+++ b/xen/include/asm-x86/setup.h
@@ -3,7 +3,6 @@
#include <xen/multiboot.h>
-extern bool_t early_boot;
extern unsigned long xenheap_initial_phys_start;
void init_done(void);
diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h
index fd03f74c8b..8e12a52507 100644
--- a/xen/include/xen/kernel.h
+++ b/xen/include/xen/kernel.h
@@ -81,5 +81,13 @@ extern char _sinittext[], _einittext[];
(__p >= _sinittext) && (__p <= _einittext); \
})
+extern enum system_state {
+ SYS_STATE_early_boot,
+ SYS_STATE_boot,
+ SYS_STATE_active,
+ SYS_STATE_suspend,
+ SYS_STATE_resume
+} system_state;
+
#endif /* _LINUX_KERNEL_H */