diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-05-30 20:33:02 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-02 07:25:34 -0400 |
commit | 9c7a794209f8a91f47697c3be20597eb60531e6d (patch) | |
tree | c1cdc49e4cf4ee5f80ea24a36e4f9498bdeeaf6b /arch/x86 | |
parent | e2426cf85f8db5891fb5831323d2d0c176c4dadc (diff) |
xen: restore vcpu_info mapping
If we're using vcpu_info mapping, then make sure its restored on all
processors before relasing them from stop_machine.
The only complication is that if this fails, we can't continue because
we've already made assumptions that the mapping is available (baked in
calls to the _direct versions of the functions, for example).
Fortunately this can only happen with a 32-bit hypervisor, which may
possibly run out of mapping space. On a 64-bit hypervisor, this is a
non-issue.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/xen/enlighten.c | 30 | ||||
-rw-r--r-- | arch/x86/xen/suspend.c | 4 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 1 |
3 files changed, 33 insertions, 2 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index ed9f04b3836d..8e6152e6ed88 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -98,7 +98,7 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info; | |||
98 | */ | 98 | */ |
99 | static int have_vcpu_info_placement = 1; | 99 | static int have_vcpu_info_placement = 1; |
100 | 100 | ||
101 | static void __init xen_vcpu_setup(int cpu) | 101 | static void xen_vcpu_setup(int cpu) |
102 | { | 102 | { |
103 | struct vcpu_register_vcpu_info info; | 103 | struct vcpu_register_vcpu_info info; |
104 | int err; | 104 | int err; |
@@ -136,6 +136,34 @@ static void __init xen_vcpu_setup(int cpu) | |||
136 | } | 136 | } |
137 | } | 137 | } |
138 | 138 | ||
139 | /* | ||
140 | * On restore, set the vcpu placement up again. | ||
141 | * If it fails, then we're in a bad state, since | ||
142 | * we can't back out from using it... | ||
143 | */ | ||
144 | void xen_vcpu_restore(void) | ||
145 | { | ||
146 | if (have_vcpu_info_placement) { | ||
147 | int cpu; | ||
148 | |||
149 | for_each_online_cpu(cpu) { | ||
150 | bool other_cpu = (cpu != smp_processor_id()); | ||
151 | |||
152 | if (other_cpu && | ||
153 | HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL)) | ||
154 | BUG(); | ||
155 | |||
156 | xen_vcpu_setup(cpu); | ||
157 | |||
158 | if (other_cpu && | ||
159 | HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)) | ||
160 | BUG(); | ||
161 | } | ||
162 | |||
163 | BUG_ON(!have_vcpu_info_placement); | ||
164 | } | ||
165 | } | ||
166 | |||
139 | static void __init xen_banner(void) | 167 | static void __init xen_banner(void) |
140 | { | 168 | { |
141 | printk(KERN_INFO "Booting paravirtualized kernel on %s\n", | 169 | printk(KERN_INFO "Booting paravirtualized kernel on %s\n", |
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index 7620a16fe535..7ab10f6b39a5 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c | |||
@@ -26,6 +26,8 @@ void xen_pre_suspend(void) | |||
26 | 26 | ||
27 | void xen_post_suspend(int suspend_cancelled) | 27 | void xen_post_suspend(int suspend_cancelled) |
28 | { | 28 | { |
29 | xen_setup_shared_info(); | ||
30 | |||
29 | if (suspend_cancelled) { | 31 | if (suspend_cancelled) { |
30 | xen_start_info->store_mfn = | 32 | xen_start_info->store_mfn = |
31 | pfn_to_mfn(xen_start_info->store_mfn); | 33 | pfn_to_mfn(xen_start_info->store_mfn); |
@@ -35,8 +37,8 @@ void xen_post_suspend(int suspend_cancelled) | |||
35 | #ifdef CONFIG_SMP | 37 | #ifdef CONFIG_SMP |
36 | xen_cpu_initialized_map = cpu_online_map; | 38 | xen_cpu_initialized_map = cpu_online_map; |
37 | #endif | 39 | #endif |
40 | xen_vcpu_restore(); | ||
38 | } | 41 | } |
39 | 42 | ||
40 | xen_setup_shared_info(); | ||
41 | } | 43 | } |
42 | 44 | ||
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index a0503acad664..a457e03e1b21 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -26,6 +26,7 @@ char * __init xen_memory_setup(void); | |||
26 | void __init xen_arch_setup(void); | 26 | void __init xen_arch_setup(void); |
27 | void __init xen_init_IRQ(void); | 27 | void __init xen_init_IRQ(void); |
28 | void xen_enable_sysenter(void); | 28 | void xen_enable_sysenter(void); |
29 | void xen_vcpu_restore(void); | ||
29 | 30 | ||
30 | void __init xen_build_dynamic_phys_to_machine(void); | 31 | void __init xen_build_dynamic_phys_to_machine(void); |
31 | 32 | ||