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