diff options
Diffstat (limited to 'arch/x86/xen/suspend.c')
| -rw-r--r-- | arch/x86/xen/suspend.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index 95be7b43472..c4df9dbd63b 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c @@ -1,4 +1,5 @@ #include <linux/types.h> +#include <linux/clockchips.h> #include <xen/interface/xen.h> #include <xen/grant_table.h> @@ -11,8 +12,10 @@ #include "xen-ops.h" #include "mmu.h" -void xen_pre_suspend(void) +static void xen_pv_pre_suspend(void) { + xen_mm_pin_all(); + xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); xen_start_info->console.domU.mfn = mfn_to_pfn(xen_start_info->console.domU.mfn); @@ -25,8 +28,25 @@ void xen_pre_suspend(void) BUG(); } -void xen_post_suspend(int suspend_cancelled) +static void xen_hvm_post_suspend(int suspend_cancelled) { +#ifdef CONFIG_XEN_PVHVM + int cpu; + xen_hvm_init_shared_info(); + xen_callback_vector(); + xen_unplug_emulated_devices(); + if (xen_feature(XENFEAT_hvm_safe_pvclock)) { + for_each_online_cpu(cpu) { + xen_setup_runstate_info(cpu); + } + } +#endif +} + +static void xen_pv_post_suspend(int suspend_cancelled) +{ + xen_build_mfn_list_list(); + xen_setup_shared_info(); if (suspend_cancelled) { @@ -42,9 +62,36 @@ void xen_post_suspend(int suspend_cancelled) xen_vcpu_restore(); } + xen_mm_unpin_all(); +} + +void xen_arch_pre_suspend(void) +{ + if (xen_pv_domain()) + xen_pv_pre_suspend(); +} + +void xen_arch_post_suspend(int cancelled) +{ + if (xen_pv_domain()) + xen_pv_post_suspend(cancelled); + else + xen_hvm_post_suspend(cancelled); +} + +static void xen_vcpu_notify_restore(void *data) +{ + unsigned long reason = (unsigned long)data; + + /* Boot processor notified via generic timekeeping_resume() */ + if ( smp_processor_id() == 0) + return; + + clockevents_notify(reason, NULL); } void xen_arch_resume(void) { - /* nothing */ + on_each_cpu(xen_vcpu_notify_restore, + (void *)CLOCK_EVT_NOTIFY_RESUME, 1); } |
