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