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 xen_hvm_init_shared_info(); 38 xen_callback_vector(); 39 xen_unplug_emulated_devices(); 40 if (xen_feature(XENFEAT_hvm_safe_pvclock)) { 41 for_each_online_cpu(cpu) { 42 xen_setup_runstate_info(cpu); 43 } 44 } 45 #endif 46 } 47 48 static void xen_pv_post_suspend(int suspend_cancelled) 49 { 50 xen_build_mfn_list_list(); 51 52 xen_setup_shared_info(); 53 54 if (suspend_cancelled) { 55 xen_start_info->store_mfn = 56 pfn_to_mfn(xen_start_info->store_mfn); 57 xen_start_info->console.domU.mfn = 58 pfn_to_mfn(xen_start_info->console.domU.mfn); 59 } else { 60 #ifdef CONFIG_SMP 61 BUG_ON(xen_cpu_initialized_map == NULL); 62 cpumask_copy(xen_cpu_initialized_map, cpu_online_mask); 63 #endif 64 xen_vcpu_restore(); 65 } 66 67 xen_mm_unpin_all(); 68 } 69 70 void xen_arch_pre_suspend(void) 71 { 72 if (xen_pv_domain()) 73 xen_pv_pre_suspend(); 74 } 75 76 void xen_arch_post_suspend(int cancelled) 77 { 78 if (xen_pv_domain()) 79 xen_pv_post_suspend(cancelled); 80 else 81 xen_hvm_post_suspend(cancelled); 82 } 83 84 static void xen_vcpu_notify_restore(void *data) 85 { 86 /* Boot processor notified via generic timekeeping_resume() */ 87 if (smp_processor_id() == 0) 88 return; 89 90 tick_resume_local(); 91 } 92 93 static void xen_vcpu_notify_suspend(void *data) 94 { 95 tick_suspend_local(); 96 } 97 98 void xen_arch_resume(void) 99 { 100 int cpu; 101 102 on_each_cpu(xen_vcpu_notify_restore, NULL, 1); 103 104 for_each_online_cpu(cpu) 105 xen_pmu_init(cpu); 106 } 107 108 void xen_arch_suspend(void) 109 { 110 int cpu; 111 112 for_each_online_cpu(cpu) 113 xen_pmu_finish(cpu); 114 115 on_each_cpu(xen_vcpu_notify_suspend, NULL, 1); 116 } 117