diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/xen/manage.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index a6bd2e9ca106..5b7a0a9402e7 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -37,6 +37,8 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; | |||
37 | struct suspend_info { | 37 | struct suspend_info { |
38 | int cancelled; | 38 | int cancelled; |
39 | unsigned long arg; /* extra hypercall argument */ | 39 | unsigned long arg; /* extra hypercall argument */ |
40 | void (*pre)(void); | ||
41 | void (*post)(int cancelled); | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | static void xen_hvm_post_suspend(int cancelled) | 44 | static void xen_hvm_post_suspend(int cancelled) |
@@ -74,6 +76,9 @@ static int xen_hvm_suspend(void *data) | |||
74 | return err; | 76 | return err; |
75 | } | 77 | } |
76 | 78 | ||
79 | if (si->pre) | ||
80 | si->pre(); | ||
81 | |||
77 | /* | 82 | /* |
78 | * This hypercall returns 1 if suspend was cancelled | 83 | * This hypercall returns 1 if suspend was cancelled |
79 | * or the domain was merely checkpointed, and 0 if it | 84 | * or the domain was merely checkpointed, and 0 if it |
@@ -81,7 +86,8 @@ static int xen_hvm_suspend(void *data) | |||
81 | */ | 86 | */ |
82 | si->cancelled = HYPERVISOR_suspend(si->arg); | 87 | si->cancelled = HYPERVISOR_suspend(si->arg); |
83 | 88 | ||
84 | xen_hvm_post_suspend(si->cancelled); | 89 | if (si->post) |
90 | si->post(si->cancelled); | ||
85 | 91 | ||
86 | if (!si->cancelled) { | 92 | if (!si->cancelled) { |
87 | xen_irq_resume(); | 93 | xen_irq_resume(); |
@@ -108,7 +114,8 @@ static int xen_suspend(void *data) | |||
108 | return err; | 114 | return err; |
109 | } | 115 | } |
110 | 116 | ||
111 | xen_pre_suspend(); | 117 | if (si->pre) |
118 | si->pre(); | ||
112 | 119 | ||
113 | /* | 120 | /* |
114 | * This hypercall returns 1 if suspend was cancelled | 121 | * This hypercall returns 1 if suspend was cancelled |
@@ -117,7 +124,8 @@ static int xen_suspend(void *data) | |||
117 | */ | 124 | */ |
118 | si->cancelled = HYPERVISOR_suspend(si->arg); | 125 | si->cancelled = HYPERVISOR_suspend(si->arg); |
119 | 126 | ||
120 | xen_post_suspend(si->cancelled); | 127 | if (si->post) |
128 | si->post(si->cancelled); | ||
121 | 129 | ||
122 | if (!si->cancelled) { | 130 | if (!si->cancelled) { |
123 | xen_irq_resume(); | 131 | xen_irq_resume(); |
@@ -165,10 +173,15 @@ static void do_suspend(void) | |||
165 | 173 | ||
166 | si.cancelled = 1; | 174 | si.cancelled = 1; |
167 | 175 | ||
168 | if (xen_hvm_domain()) | 176 | if (xen_hvm_domain()) { |
169 | si.arg = 0UL; | 177 | si.arg = 0UL; |
170 | else | 178 | si.pre = NULL; |
179 | si.post = &xen_hvm_post_suspend; | ||
180 | } else { | ||
171 | si.arg = virt_to_mfn(xen_start_info); | 181 | si.arg = virt_to_mfn(xen_start_info); |
182 | si.pre = &xen_pre_suspend; | ||
183 | si.post = &xen_post_suspend; | ||
184 | } | ||
172 | 185 | ||
173 | if (xen_hvm_domain()) | 186 | if (xen_hvm_domain()) |
174 | err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); | 187 | err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); |