static int xen_suspend(void *data) { int *cancelled = data; int err; BUG_ON(!irqs_disabled()); load_cr3(swapper_pg_dir); err = device_power_down(PMSG_SUSPEND); if (err) { printk(KERN_ERR "xen_suspend: device_power_down failed: %d\n", err); return err; } xen_mm_pin_all(); gnttab_suspend(); xen_pre_suspend(); /* * This hypercall returns 1 if suspend was cancelled * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ *cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); xen_post_suspend(*cancelled); gnttab_resume(); xen_mm_unpin_all(); device_power_up(PMSG_RESUME); if (!*cancelled) { xen_irq_resume(); xen_console_resume(); xen_timer_resume(); } return 0; }
static void xen_pv_post_suspend(int suspend_cancelled) { xen_build_mfn_list_list(); xen_setup_shared_info(); if (suspend_cancelled) { xen_start_info->store_mfn = pfn_to_mfn(xen_start_info->store_mfn); xen_start_info->console.domU.mfn = pfn_to_mfn(xen_start_info->console.domU.mfn); } else { #ifdef CONFIG_SMP BUG_ON(xen_cpu_initialized_map == NULL); cpumask_copy(xen_cpu_initialized_map, cpu_online_mask); #endif xen_vcpu_restore(); } xen_mm_unpin_all(); }
static void xen_post_suspend(int cancelled) { xen_arch_post_suspend(cancelled); gnttab_resume(); xen_mm_unpin_all(); }