1#include <linux/types.h> 2#include <linux/tick.h> 3 4#include <xen/xen.h> 5#include <xen/interface/xen.h> 6#include <xen/grant_table.h> 7#include <xen/events.h> 8 9#include <asm/xen/hypercall.h> 10#include <asm/xen/page.h> 11#include <asm/fixmap.h> 12 13#include "xen-ops.h" 14#include "mmu.h" 15#include "pmu.h" 16 17static void xen_pv_pre_suspend(void) 18{ 19 xen_mm_pin_all(); 20 21 xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); 22 xen_start_info->console.domU.mfn = 23 mfn_to_pfn(xen_start_info->console.domU.mfn); 24 25 BUG_ON(!irqs_disabled()); 26 27 HYPERVISOR_shared_info = &xen_dummy_shared_info; 28 if (HYPERVISOR_update_va_mapping(fix_to_virt(FIX_PARAVIRT_BOOTMAP), 29 __pte_ma(0), 0)) 30 BUG(); 31} 32 33static void xen_hvm_post_suspend(int suspend_cancelled) 34{ 35#ifdef CONFIG_XEN_PVHVM 36 int cpu; 37 if (!suspend_cancelled) 38 xen_hvm_init_shared_info(); 39 xen_callback_vector(); 40 xen_unplug_emulated_devices(); 41 if (xen_feature(XENFEAT_hvm_safe_pvclock)) { 42 for_each_online_cpu(cpu) { 43 xen_setup_runstate_info(cpu); 44 } 45 } 46#endif 47} 48 49static void xen_pv_post_suspend(int suspend_cancelled) 50{ 51 xen_build_mfn_list_list(); 52 53 xen_setup_shared_info(); 54 55 if (suspend_cancelled) { 56 xen_start_info->store_mfn = 57 pfn_to_mfn(xen_start_info->store_mfn); 58 xen_start_info->console.domU.mfn = 59 pfn_to_mfn(xen_start_info->console.domU.mfn); 60 } else { 61#ifdef CONFIG_SMP 62 BUG_ON(xen_cpu_initialized_map == NULL); 63 cpumask_copy(xen_cpu_initialized_map, cpu_online_mask); 64#endif 65 xen_vcpu_restore(); 66 } 67 68 xen_mm_unpin_all(); 69} 70 71void xen_arch_pre_suspend(void) 72{ 73 if (xen_pv_domain()) 74 xen_pv_pre_suspend(); 75} 76 77void xen_arch_post_suspend(int cancelled) 78{ 79 if (xen_pv_domain()) 80 xen_pv_post_suspend(cancelled); 81 else 82 xen_hvm_post_suspend(cancelled); 83} 84 85static void xen_vcpu_notify_restore(void *data) 86{ 87 /* Boot processor notified via generic timekeeping_resume() */ 88 if (smp_processor_id() == 0) 89 return; 90 91 tick_resume_local(); 92} 93 94static void xen_vcpu_notify_suspend(void *data) 95{ 96 tick_suspend_local(); 97} 98 99void xen_arch_resume(void) 100{ 101 int cpu; 102 103 on_each_cpu(xen_vcpu_notify_restore, NULL, 1); 104 105 for_each_online_cpu(cpu) 106 xen_pmu_init(cpu); 107} 108 109void xen_arch_suspend(void) 110{ 111 int cpu; 112 113 for_each_online_cpu(cpu) 114 xen_pmu_finish(cpu); 115 116 on_each_cpu(xen_vcpu_notify_suspend, NULL, 1); 117} 118