aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/manage.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/manage.c')
-rw-r--r--drivers/xen/manage.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 07e857b0de13..1799bd890315 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -9,6 +9,7 @@
9#include <linux/stop_machine.h> 9#include <linux/stop_machine.h>
10#include <linux/freezer.h> 10#include <linux/freezer.h>
11 11
12#include <xen/xen.h>
12#include <xen/xenbus.h> 13#include <xen/xenbus.h>
13#include <xen/grant_table.h> 14#include <xen/grant_table.h>
14#include <xen/events.h> 15#include <xen/events.h>
@@ -17,6 +18,7 @@
17 18
18#include <asm/xen/hypercall.h> 19#include <asm/xen/hypercall.h>
19#include <asm/xen/page.h> 20#include <asm/xen/page.h>
21#include <asm/xen/hypervisor.h>
20 22
21enum shutdown_state { 23enum shutdown_state {
22 SHUTDOWN_INVALID = -1, 24 SHUTDOWN_INVALID = -1,
@@ -33,10 +35,30 @@ enum shutdown_state {
33static enum shutdown_state shutting_down = SHUTDOWN_INVALID; 35static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
34 36
35#ifdef CONFIG_PM_SLEEP 37#ifdef CONFIG_PM_SLEEP
36static int xen_suspend(void *data) 38static int xen_hvm_suspend(void *data)
37{ 39{
40 struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
38 int *cancelled = data; 41 int *cancelled = data;
42
43 BUG_ON(!irqs_disabled());
44
45 *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
46
47 xen_hvm_post_suspend(*cancelled);
48 gnttab_resume();
49
50 if (!*cancelled) {
51 xen_irq_resume();
52 xen_timer_resume();
53 }
54
55 return 0;
56}
57
58static int xen_suspend(void *data)
59{
39 int err; 60 int err;
61 int *cancelled = data;
40 62
41 BUG_ON(!irqs_disabled()); 63 BUG_ON(!irqs_disabled());
42 64
@@ -106,7 +128,10 @@ static void do_suspend(void)
106 goto out_resume; 128 goto out_resume;
107 } 129 }
108 130
109 err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); 131 if (xen_hvm_domain())
132 err = stop_machine(xen_hvm_suspend, &cancelled, cpumask_of(0));
133 else
134 err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
110 135
111 dpm_resume_noirq(PMSG_RESUME); 136 dpm_resume_noirq(PMSG_RESUME);
112 137
@@ -255,7 +280,19 @@ static int shutdown_event(struct notifier_block *notifier,
255 return NOTIFY_DONE; 280 return NOTIFY_DONE;
256} 281}
257 282
258static int __init setup_shutdown_event(void) 283static int __init __setup_shutdown_event(void)
284{
285 /* Delay initialization in the PV on HVM case */
286 if (xen_hvm_domain())
287 return 0;
288
289 if (!xen_pv_domain())
290 return -ENODEV;
291
292 return xen_setup_shutdown_event();
293}
294
295int xen_setup_shutdown_event(void)
259{ 296{
260 static struct notifier_block xenstore_notifier = { 297 static struct notifier_block xenstore_notifier = {
261 .notifier_call = shutdown_event 298 .notifier_call = shutdown_event
@@ -264,5 +301,6 @@ static int __init setup_shutdown_event(void)
264 301
265 return 0; 302 return 0;
266} 303}
304EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
267 305
268subsys_initcall(setup_shutdown_event); 306subsys_initcall(__setup_shutdown_event);