]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.xen/xen-sysdev-suspend
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.xen / xen-sysdev-suspend
CommitLineData
2cb7cef9
BS
1From: jbeulich@novell.com
2Subject: use base kernel suspend/resume infrastructure
3Patch-mainline: obsolete
4
5... rather than calling just a few functions explicitly.
6
82094b55
AF
7--- sle11-2009-10-16.orig/arch/x86/kernel/time_32-xen.c 2009-10-28 14:59:14.000000000 +0100
8+++ sle11-2009-10-16/arch/x86/kernel/time_32-xen.c 2009-10-28 14:59:22.000000000 +0100
2cb7cef9
BS
9@@ -88,6 +88,10 @@ static DEFINE_PER_CPU(struct vcpu_runsta
10 /* Must be signed, as it's compared with s64 quantities which can be -ve. */
11 #define NS_PER_TICK (1000000000LL/HZ)
12
13+static struct vcpu_set_periodic_timer xen_set_periodic_tick = {
14+ .period_ns = NS_PER_TICK
15+};
16+
17 static void __clock_was_set(struct work_struct *unused)
18 {
19 clock_was_set();
82094b55 20@@ -598,6 +602,25 @@ void mark_tsc_unstable(char *reason)
2cb7cef9
BS
21 }
22 EXPORT_SYMBOL_GPL(mark_tsc_unstable);
23
24+static void init_missing_ticks_accounting(unsigned int cpu)
25+{
26+ struct vcpu_register_runstate_memory_area area;
27+ struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
28+ int rc;
29+
30+ memset(runstate, 0, sizeof(*runstate));
31+
32+ area.addr.v = runstate;
33+ rc = HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, cpu, &area);
34+ WARN_ON(rc && rc != -ENOSYS);
35+
36+ per_cpu(processed_blocked_time, cpu) =
37+ runstate->time[RUNSTATE_blocked];
38+ per_cpu(processed_stolen_time, cpu) =
39+ runstate->time[RUNSTATE_runnable] +
40+ runstate->time[RUNSTATE_offline];
41+}
42+
43 static cycle_t cs_last;
44
45 static cycle_t xen_clocksource_read(void)
82094b55 46@@ -634,11 +657,32 @@ static cycle_t xen_clocksource_read(void
2cb7cef9
BS
47 #endif
48 }
49
50+/* No locking required. Interrupts are disabled on all CPUs. */
51 static void xen_clocksource_resume(void)
52 {
53- extern void time_resume(void);
54+ unsigned int cpu;
55+
56+ init_cpu_khz();
57+
58+ for_each_online_cpu(cpu) {
59+ switch (HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
60+ &xen_set_periodic_tick)) {
61+ case 0:
62+#if CONFIG_XEN_COMPAT <= 0x030004
63+ case -ENOSYS:
64+#endif
65+ break;
66+ default:
67+ BUG();
68+ }
69+ get_time_values_from_xen(cpu);
70+ per_cpu(processed_system_time, cpu) =
71+ per_cpu(shadow_time, 0).system_timestamp;
72+ init_missing_ticks_accounting(cpu);
73+ }
74+
75+ processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
76
77- time_resume();
78 cs_last = local_clock();
79 }
80
82094b55 81@@ -653,25 +697,6 @@ static struct clocksource clocksource_xe
2cb7cef9
BS
82 .resume = xen_clocksource_resume,
83 };
84
85-static void init_missing_ticks_accounting(unsigned int cpu)
86-{
87- struct vcpu_register_runstate_memory_area area;
88- struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
89- int rc;
90-
91- memset(runstate, 0, sizeof(*runstate));
92-
93- area.addr.v = runstate;
94- rc = HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, cpu, &area);
95- WARN_ON(rc && rc != -ENOSYS);
96-
97- per_cpu(processed_blocked_time, cpu) =
98- runstate->time[RUNSTATE_blocked];
99- per_cpu(processed_stolen_time, cpu) =
100- runstate->time[RUNSTATE_runnable] +
101- runstate->time[RUNSTATE_offline];
102-}
103-
104 unsigned long xen_read_persistent_clock(void)
105 {
106 const shared_info_t *s = HYPERVISOR_shared_info;
82094b55 107@@ -716,10 +741,6 @@ static void __init setup_cpu0_timer_irq(
2cb7cef9
BS
108 BUG_ON(per_cpu(timer_irq, 0) < 0);
109 }
110
111-static struct vcpu_set_periodic_timer xen_set_periodic_tick = {
112- .period_ns = NS_PER_TICK
113-};
114-
115 void __init time_init(void)
116 {
117 init_cpu_khz();
82094b55 118@@ -843,35 +864,6 @@ void xen_halt(void)
2cb7cef9
BS
119 }
120 EXPORT_SYMBOL(xen_halt);
121
122-/* No locking required. Interrupts are disabled on all CPUs. */
123-void time_resume(void)
124-{
125- unsigned int cpu;
126-
127- init_cpu_khz();
128-
129- for_each_online_cpu(cpu) {
130- switch (HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
131- &xen_set_periodic_tick)) {
132- case 0:
133-#if CONFIG_XEN_COMPAT <= 0x030004
134- case -ENOSYS:
135-#endif
136- break;
137- default:
138- BUG();
139- }
140- get_time_values_from_xen(cpu);
141- per_cpu(processed_system_time, cpu) =
142- per_cpu(shadow_time, 0).system_timestamp;
143- init_missing_ticks_accounting(cpu);
144- }
145-
146- processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
147-
148- update_wallclock();
149-}
150-
151 #ifdef CONFIG_SMP
152 static char timer_name[NR_CPUS][15];
153
82094b55
AF
154--- sle11-2009-10-16.orig/drivers/xen/core/evtchn.c 2009-06-04 10:21:39.000000000 +0200
155+++ sle11-2009-10-16/drivers/xen/core/evtchn.c 2009-01-14 14:57:55.000000000 +0100
2cb7cef9
BS
156@@ -35,6 +35,7 @@
157 #include <linux/interrupt.h>
158 #include <linux/sched.h>
159 #include <linux/kernel_stat.h>
160+#include <linux/sysdev.h>
161 #include <linux/bootmem.h>
162 #include <linux/version.h>
163 #include <asm/atomic.h>
164@@ -1070,9 +1071,20 @@ static void restore_cpu_ipis(unsigned in
165 }
166 }
167
168-void irq_resume(void)
169+static int evtchn_resume(struct sys_device *dev)
170 {
171 unsigned int cpu, irq, evtchn;
172+ struct evtchn_status status;
173+
174+ /* Avoid doing anything in the 'suspend cancelled' case. */
175+ status.dom = DOMID_SELF;
176+ status.port = evtchn_from_irq(__get_cpu_var(virq_to_irq)[VIRQ_TIMER]);
177+ if (HYPERVISOR_event_channel_op(EVTCHNOP_status, &status))
178+ BUG();
179+ if (status.status == EVTCHNSTAT_virq
180+ && status.vcpu == smp_processor_id()
181+ && status.u.virq == VIRQ_TIMER)
182+ return 0;
183
184 init_evtchn_cpu_bindings();
185
186@@ -1103,7 +1115,32 @@ void irq_resume(void)
187 restore_cpu_ipis(cpu);
188 }
189
190+ return 0;
191+}
192+
193+static struct sysdev_class evtchn_sysclass = {
194+ .name = "evtchn",
195+ .resume = evtchn_resume,
196+};
197+
198+static struct sys_device device_evtchn = {
199+ .id = 0,
200+ .cls = &evtchn_sysclass,
201+};
202+
203+static int __init evtchn_register(void)
204+{
205+ int err;
206+
207+ if (is_initial_xendomain())
208+ return 0;
209+
210+ err = sysdev_class_register(&evtchn_sysclass);
211+ if (!err)
212+ err = sysdev_register(&device_evtchn);
213+ return err;
214 }
215+core_initcall(evtchn_register);
216 #endif
217
218 #if defined(CONFIG_X86_IO_APIC)
82094b55
AF
219--- sle11-2009-10-16.orig/drivers/xen/core/gnttab.c 2009-06-04 10:21:39.000000000 +0200
220+++ sle11-2009-10-16/drivers/xen/core/gnttab.c 2008-12-15 11:32:52.000000000 +0100
2cb7cef9
BS
221@@ -35,6 +35,7 @@
222 #include <linux/sched.h>
223 #include <linux/mm.h>
224 #include <linux/seqlock.h>
225+#include <linux/sysdev.h>
226 #include <xen/interface/xen.h>
227 #include <xen/gnttab.h>
228 #include <asm/pgtable.h>
229@@ -704,23 +705,37 @@ EXPORT_SYMBOL(gnttab_post_map_adjust);
230
231 #endif /* __HAVE_ARCH_PTE_SPECIAL */
232
233-int gnttab_resume(void)
234+static int gnttab_resume(struct sys_device *dev)
235 {
236 if (max_nr_grant_frames() < nr_grant_frames)
237 return -ENOSYS;
238 return gnttab_map(0, nr_grant_frames - 1);
239 }
240+#define gnttab_resume() gnttab_resume(NULL)
241
242 #ifdef CONFIG_PM_SLEEP
243-int gnttab_suspend(void)
244-{
245 #ifdef CONFIG_X86
246+static int gnttab_suspend(struct sys_device *dev, pm_message_t state)
247+{
248 apply_to_page_range(&init_mm, (unsigned long)shared,
249 PAGE_SIZE * nr_grant_frames,
250 unmap_pte_fn, NULL);
251-#endif
252 return 0;
253 }
254+#else
255+#define gnttab_suspend NULL
256+#endif
257+
258+static struct sysdev_class gnttab_sysclass = {
259+ .name = "gnttab",
260+ .resume = gnttab_resume,
261+ .suspend = gnttab_suspend,
262+};
263+
264+static struct sys_device device_gnttab = {
265+ .id = 0,
266+ .cls = &gnttab_sysclass,
267+};
268 #endif
269
270 #else /* !CONFIG_XEN */
271@@ -800,6 +815,17 @@ int __devinit gnttab_init(void)
272 if (!is_running_on_xen())
273 return -ENODEV;
274
275+#if defined(CONFIG_XEN) && defined(CONFIG_PM_SLEEP)
276+ if (!is_initial_xendomain()) {
277+ int err = sysdev_class_register(&gnttab_sysclass);
278+
279+ if (!err)
280+ err = sysdev_register(&device_gnttab);
281+ if (err)
282+ return err;
283+ }
284+#endif
285+
286 nr_grant_frames = 1;
287 boot_max_nr_grant_frames = __max_nr_grant_frames();
288
82094b55
AF
289--- sle11-2009-10-16.orig/drivers/xen/core/machine_reboot.c 2009-06-04 10:21:39.000000000 +0200
290+++ sle11-2009-10-16/drivers/xen/core/machine_reboot.c 2009-02-17 12:23:48.000000000 +0100
2cb7cef9
BS
291@@ -17,6 +17,7 @@
292 #include <xen/xencons.h>
293 #include <xen/cpu_hotplug.h>
294 #include <xen/interface/vcpu.h>
295+#include "../../base/base.h"
296
297 #if defined(__i386__) || defined(__x86_64__)
298
299@@ -141,7 +142,6 @@ static int take_machine_down(void *_susp
300 {
301 struct suspend *suspend = _suspend;
302 int suspend_cancelled, err;
303- extern void time_resume(void);
304
305 if (suspend->fast_suspend) {
306 BUG_ON(!irqs_disabled());
307@@ -167,20 +167,23 @@ static int take_machine_down(void *_susp
308 }
309
310 mm_pin_all();
311- gnttab_suspend();
312- pre_suspend();
313-
314- /*
315- * This hypercall returns 1 if suspend was cancelled or the domain was
316- * merely checkpointed, and 0 if it is resuming in a new domain.
317- */
318- suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
319+ suspend_cancelled = sysdev_suspend(PMSG_FREEZE);
320+ if (!suspend_cancelled) {
321+ pre_suspend();
322
323+ /*
324+ * This hypercall returns 1 if suspend was cancelled or the domain was
325+ * merely checkpointed, and 0 if it is resuming in a new domain.
326+ */
327+ suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
328+ } else
329+ BUG_ON(suspend_cancelled > 0);
330 suspend->resume_notifier(suspend_cancelled);
331- post_suspend(suspend_cancelled);
332- gnttab_resume();
333+ if (suspend_cancelled >= 0) {
334+ post_suspend(suspend_cancelled);
335+ sysdev_resume();
336+ }
337 if (!suspend_cancelled) {
338- irq_resume();
339 #ifdef __x86_64__
340 /*
341 * Older versions of Xen do not save/restore the user %cr3.
342@@ -192,7 +195,6 @@ static int take_machine_down(void *_susp
343 current->active_mm->pgd)));
344 #endif
345 }
346- time_resume();
347
348 if (!suspend->fast_suspend)
349 local_irq_enable();
82094b55
AF
350--- sle11-2009-10-16.orig/include/xen/evtchn.h 2009-03-16 16:33:40.000000000 +0100
351+++ sle11-2009-10-16/include/xen/evtchn.h 2008-12-15 11:32:52.000000000 +0100
2cb7cef9
BS
352@@ -93,7 +93,9 @@ int bind_ipi_to_irqhandler(
353 */
354 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
355
356+#ifndef CONFIG_XEN
357 void irq_resume(void);
358+#endif
359
360 /* Entry point for notifications into Linux subsystems. */
361 asmlinkage void evtchn_do_upcall(struct pt_regs *regs);
82094b55
AF
362--- sle11-2009-10-16.orig/include/xen/gnttab.h 2009-10-28 14:54:56.000000000 +0100
363+++ sle11-2009-10-16/include/xen/gnttab.h 2008-12-15 11:32:52.000000000 +0100
2cb7cef9
BS
364@@ -110,8 +110,9 @@ static inline void __gnttab_dma_unmap_pa
365
366 void gnttab_reset_grant_page(struct page *page);
367
368-int gnttab_suspend(void);
369+#ifndef CONFIG_XEN
370 int gnttab_resume(void);
371+#endif
372
373 void *arch_gnttab_alloc_shared(unsigned long *frames);
374