aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2014-05-08 06:09:23 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2014-05-12 12:19:56 -0400
commitaa8532c32216ae07c3813b9aeb774517878a7573 (patch)
tree4a718b5c8ba94d2d73e83ad7e50e3796a41b345f /drivers/xen
parent9f1d341415b9d84fcf0cb04f409bd61fac5e2f14 (diff)
xen: refactor suspend pre/post hooks
New architectures currently have to provide implementations of 5 different functions: xen_arch_pre_suspend(), xen_arch_post_suspend(), xen_arch_hvm_post_suspend(), xen_mm_pin_all(), and xen_mm_unpin_all(). Refactor the suspend code to only require xen_arch_pre_suspend() and xen_arch_post_suspend(). Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/manage.c45
1 files changed, 7 insertions, 38 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 32f9236c959f..c3667b202f2f 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -41,9 +41,6 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
41 41
42struct suspend_info { 42struct suspend_info {
43 int cancelled; 43 int cancelled;
44 unsigned long arg; /* extra hypercall argument */
45 void (*pre)(void);
46 void (*post)(int cancelled);
47}; 44};
48 45
49static RAW_NOTIFIER_HEAD(xen_resume_notifier); 46static RAW_NOTIFIER_HEAD(xen_resume_notifier);
@@ -61,26 +58,6 @@ void xen_resume_notifier_unregister(struct notifier_block *nb)
61EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister); 58EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
62 59
63#ifdef CONFIG_HIBERNATE_CALLBACKS 60#ifdef CONFIG_HIBERNATE_CALLBACKS
64static void xen_hvm_post_suspend(int cancelled)
65{
66 xen_arch_hvm_post_suspend(cancelled);
67 gnttab_resume();
68}
69
70static void xen_pre_suspend(void)
71{
72 xen_mm_pin_all();
73 gnttab_suspend();
74 xen_arch_pre_suspend();
75}
76
77static void xen_post_suspend(int cancelled)
78{
79 xen_arch_post_suspend(cancelled);
80 gnttab_resume();
81 xen_mm_unpin_all();
82}
83
84static int xen_suspend(void *data) 61static int xen_suspend(void *data)
85{ 62{
86 struct suspend_info *si = data; 63 struct suspend_info *si = data;
@@ -94,18 +71,20 @@ static int xen_suspend(void *data)
94 return err; 71 return err;
95 } 72 }
96 73
97 if (si->pre) 74 gnttab_suspend();
98 si->pre(); 75 xen_arch_pre_suspend();
99 76
100 /* 77 /*
101 * This hypercall returns 1 if suspend was cancelled 78 * This hypercall returns 1 if suspend was cancelled
102 * or the domain was merely checkpointed, and 0 if it 79 * or the domain was merely checkpointed, and 0 if it
103 * is resuming in a new domain. 80 * is resuming in a new domain.
104 */ 81 */
105 si->cancelled = HYPERVISOR_suspend(si->arg); 82 si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
83 ? virt_to_mfn(xen_start_info)
84 : 0);
106 85
107 if (si->post) 86 xen_arch_post_suspend(si->cancelled);
108 si->post(si->cancelled); 87 gnttab_resume();
109 88
110 if (!si->cancelled) { 89 if (!si->cancelled) {
111 xen_irq_resume(); 90 xen_irq_resume();
@@ -154,16 +133,6 @@ static void do_suspend(void)
154 133
155 si.cancelled = 1; 134 si.cancelled = 1;
156 135
157 if (xen_hvm_domain()) {
158 si.arg = 0UL;
159 si.pre = NULL;
160 si.post = &xen_hvm_post_suspend;
161 } else {
162 si.arg = virt_to_mfn(xen_start_info);
163 si.pre = &xen_pre_suspend;
164 si.post = &xen_post_suspend;
165 }
166
167 err = stop_machine(xen_suspend, &si, cpumask_of(0)); 136 err = stop_machine(xen_suspend, &si, cpumask_of(0));
168 137
169 raw_notifier_call_chain(&xen_resume_notifier, 0, NULL); 138 raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);