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 17 static 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 33 static 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 49 static 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 71 void xen_arch_pre_suspend(void) 72 { 73 if (xen_pv_domain()) 74 xen_pv_pre_suspend(); 75 } 76 77 void 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 85 static 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 94 static void xen_vcpu_notify_suspend(void *data) 95 { 96 tick_suspend_local(); 97 } 98 99 void 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 109 void 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