1 From: jbeulich@novell.com
2 Subject: use base kernel suspend/resume infrastructure
3 Patch-mainline: obsolete
5 ... rather than calling just a few functions explicitly.
7 Index: 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)
15 +static struct vcpu_set_periodic_timer xen_set_periodic_tick = {
16 + .period_ns = NS_PER_TICK
19 static void __clock_was_set(struct work_struct *unused)
22 @@ -599,6 +603,25 @@ void mark_tsc_unstable(char *reason)
24 EXPORT_SYMBOL_GPL(mark_tsc_unstable);
26 +static void init_missing_ticks_accounting(unsigned int cpu)
28 + struct vcpu_register_runstate_memory_area area;
29 + struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
32 + memset(runstate, 0, sizeof(*runstate));
34 + area.addr.v = runstate;
35 + rc = HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, cpu, &area);
36 + WARN_ON(rc && rc != -ENOSYS);
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];
45 static cycle_t cs_last;
47 static cycle_t xen_clocksource_read(void)
48 @@ -635,11 +658,34 @@ static cycle_t xen_clocksource_read(void
52 +/* No locking required. Interrupts are disabled on all CPUs. */
53 static void xen_clocksource_resume(void)
55 - extern void time_resume(void);
60 + for_each_online_cpu(cpu) {
61 + switch (HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
62 + &xen_set_periodic_tick)) {
64 +#if CONFIG_XEN_COMPAT <= 0x030004
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);
77 + processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
82 cs_last = local_clock();
85 @@ -654,25 +700,6 @@ static struct clocksource clocksource_xe
86 .resume = xen_clocksource_resume,
89 -static void init_missing_ticks_accounting(unsigned int cpu)
91 - struct vcpu_register_runstate_memory_area area;
92 - struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
95 - memset(runstate, 0, sizeof(*runstate));
97 - area.addr.v = runstate;
98 - rc = HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, cpu, &area);
99 - WARN_ON(rc && rc != -ENOSYS);
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];
108 unsigned long xen_read_persistent_clock(void)
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);
115 -static struct vcpu_set_periodic_timer xen_set_periodic_tick = {
116 - .period_ns = NS_PER_TICK
119 void __init time_init(void)
122 @@ -844,35 +867,6 @@ void xen_halt(void)
124 EXPORT_SYMBOL(xen_halt);
126 -/* No locking required. Interrupts are disabled on all CPUs. */
127 -void time_resume(void)
133 - for_each_online_cpu(cpu) {
134 - switch (HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
135 - &xen_set_periodic_tick)) {
137 -#if CONFIG_XEN_COMPAT <= 0x030004
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);
150 - processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
152 - update_wallclock();
156 static char timer_name[NR_CPUS][15];
158 Index: 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
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
174 -void irq_resume(void)
175 +static int evtchn_resume(struct sys_device *dev)
177 unsigned int cpu, irq, evtchn;
178 + struct evtchn_status status;
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))
185 + if (status.status == EVTCHNSTAT_virq
186 + && status.vcpu == smp_processor_id()
187 + && status.u.virq == VIRQ_TIMER)
190 init_evtchn_cpu_bindings();
192 @@ -1094,7 +1106,32 @@ void irq_resume(void)
193 restore_cpu_ipis(cpu);
199 +static struct sysdev_class evtchn_sysclass = {
201 + .resume = evtchn_resume,
204 +static struct sys_device device_evtchn = {
206 + .cls = &evtchn_sysclass,
209 +static int __init evtchn_register(void)
213 + if (is_initial_xendomain())
216 + err = sysdev_class_register(&evtchn_sysclass);
218 + err = sysdev_register(&device_evtchn);
221 +core_initcall(evtchn_register);
224 #if defined(CONFIG_X86_IO_APIC)
225 Index: 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
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);
239 #endif /* __HAVE_ARCH_PTE_SPECIAL */
241 -int gnttab_resume(void)
242 +static int gnttab_resume(struct sys_device *dev)
244 if (max_nr_grant_frames() < nr_grant_frames)
246 return gnttab_map(0, nr_grant_frames - 1);
248 +#define gnttab_resume() gnttab_resume(NULL)
250 #ifdef CONFIG_PM_SLEEP
251 -int gnttab_suspend(void)
254 +static int gnttab_suspend(struct sys_device *dev, pm_message_t state)
256 apply_to_page_range(&init_mm, (unsigned long)shared,
257 PAGE_SIZE * nr_grant_frames,
263 +#define gnttab_suspend NULL
266 +static struct sysdev_class gnttab_sysclass = {
268 + .resume = gnttab_resume,
269 + .suspend = gnttab_suspend,
272 +static struct sys_device device_gnttab = {
274 + .cls = &gnttab_sysclass,
278 #else /* !CONFIG_XEN */
279 @@ -800,6 +815,17 @@ int __devinit gnttab_init(void)
280 if (!is_running_on_xen())
283 +#if defined(CONFIG_XEN) && defined(CONFIG_PM_SLEEP)
284 + if (!is_initial_xendomain()) {
285 + int err = sysdev_class_register(&gnttab_sysclass);
288 + err = sysdev_register(&device_gnttab);
295 boot_max_nr_grant_frames = __max_nr_grant_frames();
297 Index: 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
302 #include <xen/xencons.h>
303 #include <xen/cpu_hotplug.h>
304 #include <xen/interface/vcpu.h>
305 +#include "../../base/base.h"
307 #if defined(__i386__) || defined(__x86_64__)
309 @@ -149,7 +150,6 @@ static int take_machine_down(void *_susp
311 struct suspend *suspend = _suspend;
312 int suspend_cancelled, err;
313 - extern void time_resume(void);
315 if (suspend->fast_suspend) {
316 BUG_ON(!irqs_disabled());
317 @@ -175,20 +175,23 @@ static int take_machine_down(void *_susp
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.
328 - suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
329 + suspend_cancelled = sysdev_suspend(PMSG_FREEZE);
330 + if (!suspend_cancelled) {
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.
337 + suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
339 + BUG_ON(suspend_cancelled > 0);
340 suspend->resume_notifier(suspend_cancelled);
341 - post_suspend(suspend_cancelled);
343 + if (suspend_cancelled >= 0) {
344 + post_suspend(suspend_cancelled);
347 if (!suspend_cancelled) {
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)));
358 if (!suspend->fast_suspend)
360 Index: 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(
366 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
369 void irq_resume(void);
372 /* Entry point for notifications into Linux subsystems. */
373 asmlinkage void evtchn_do_upcall(struct pt_regs *regs);
374 Index: 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
380 void gnttab_reset_grant_page(struct page *page);
382 -int gnttab_suspend(void);
384 int gnttab_resume(void);
387 void *arch_gnttab_alloc_shared(unsigned long *frames);