2 * Handle extern requests for shutdown, reboot and sysrq
4 #include <linux/kernel.h>
6 #include <linux/slab.h>
7 #include <linux/reboot.h>
8 #include <linux/sysrq.h>
9 #include <linux/stop_machine.h>
10 #include <linux/freezer.h>
13 #include <xen/xenbus.h>
14 #include <xen/grant_table.h>
15 #include <xen/events.h>
16 #include <xen/hvc-console.h>
17 #include <xen/xen-ops.h>
19 #include <asm/xen/hypercall.h>
20 #include <asm/xen/page.h>
21 #include <asm/xen/hypervisor.h>
24 SHUTDOWN_INVALID
= -1,
25 SHUTDOWN_POWEROFF
= 0,
27 /* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
28 report a crash, not be instructed to crash!
29 HALT is the same as POWEROFF, as far as we're concerned. The tools use
30 the distinction when we return the reason code to them. */
34 /* Ignore multiple shutdown requests. */
35 static enum shutdown_state shutting_down
= SHUTDOWN_INVALID
;
37 #ifdef CONFIG_PM_SLEEP
38 static int xen_hvm_suspend(void *data
)
40 struct sched_shutdown r
= { .reason
= SHUTDOWN_suspend
};
41 int *cancelled
= data
;
43 BUG_ON(!irqs_disabled());
45 *cancelled
= HYPERVISOR_sched_op(SCHEDOP_shutdown
, &r
);
47 xen_hvm_post_suspend(*cancelled
);
59 static int xen_suspend(void *data
)
62 int *cancelled
= data
;
64 BUG_ON(!irqs_disabled());
66 err
= sysdev_suspend(PMSG_SUSPEND
);
68 printk(KERN_ERR
"xen_suspend: sysdev_suspend failed: %d\n",
78 * This hypercall returns 1 if suspend was cancelled
79 * or the domain was merely checkpointed, and 0 if it
80 * is resuming in a new domain.
82 *cancelled
= HYPERVISOR_suspend(virt_to_mfn(xen_start_info
));
84 xen_post_suspend(*cancelled
);
99 static void do_suspend(void)
104 shutting_down
= SHUTDOWN_SUSPEND
;
106 #ifdef CONFIG_PREEMPT
107 /* If the kernel is preemptible, we need to freeze all the processes
108 to prevent them from being in the middle of a pagetable update
110 err
= freeze_processes();
112 printk(KERN_ERR
"xen suspend: freeze failed %d\n", err
);
117 err
= dpm_suspend_start(PMSG_SUSPEND
);
119 printk(KERN_ERR
"xen suspend: dpm_suspend_start %d\n", err
);
123 printk(KERN_DEBUG
"suspending xenstore...\n");
126 err
= dpm_suspend_noirq(PMSG_SUSPEND
);
128 printk(KERN_ERR
"dpm_suspend_noirq failed: %d\n", err
);
132 if (xen_hvm_domain())
133 err
= stop_machine(xen_hvm_suspend
, &cancelled
, cpumask_of(0));
135 err
= stop_machine(xen_suspend
, &cancelled
, cpumask_of(0));
137 dpm_resume_noirq(PMSG_RESUME
);
140 printk(KERN_ERR
"failed to start xen_suspend: %d\n", err
);
151 dpm_resume_end(PMSG_RESUME
);
153 /* Make sure timer events get retriggered on all CPUs */
157 #ifdef CONFIG_PREEMPT
161 shutting_down
= SHUTDOWN_INVALID
;
163 #endif /* CONFIG_PM_SLEEP */
165 static void shutdown_handler(struct xenbus_watch
*watch
,
166 const char **vec
, unsigned int len
)
169 struct xenbus_transaction xbt
;
172 if (shutting_down
!= SHUTDOWN_INVALID
)
176 err
= xenbus_transaction_start(&xbt
);
180 str
= (char *)xenbus_read(xbt
, "control", "shutdown", NULL
);
181 /* Ignore read errors and empty reads. */
182 if (XENBUS_IS_ERR_READ(str
)) {
183 xenbus_transaction_end(xbt
, 1);
187 xenbus_write(xbt
, "control", "shutdown", "");
189 err
= xenbus_transaction_end(xbt
, 0);
190 if (err
== -EAGAIN
) {
195 if (strcmp(str
, "poweroff") == 0 ||
196 strcmp(str
, "halt") == 0) {
197 shutting_down
= SHUTDOWN_POWEROFF
;
198 orderly_poweroff(false);
199 } else if (strcmp(str
, "reboot") == 0) {
200 shutting_down
= SHUTDOWN_POWEROFF
; /* ? */
202 #ifdef CONFIG_PM_SLEEP
203 } else if (strcmp(str
, "suspend") == 0) {
207 printk(KERN_INFO
"Ignoring shutdown request: %s\n", str
);
208 shutting_down
= SHUTDOWN_INVALID
;
214 #ifdef CONFIG_MAGIC_SYSRQ
215 static void sysrq_handler(struct xenbus_watch
*watch
, const char **vec
,
218 char sysrq_key
= '\0';
219 struct xenbus_transaction xbt
;
223 err
= xenbus_transaction_start(&xbt
);
226 if (!xenbus_scanf(xbt
, "control", "sysrq", "%c", &sysrq_key
)) {
227 printk(KERN_ERR
"Unable to read sysrq code in "
229 xenbus_transaction_end(xbt
, 1);
233 if (sysrq_key
!= '\0')
234 xenbus_printf(xbt
, "control", "sysrq", "%c", '\0');
236 err
= xenbus_transaction_end(xbt
, 0);
240 if (sysrq_key
!= '\0')
241 handle_sysrq(sysrq_key
);
244 static struct xenbus_watch sysrq_watch
= {
245 .node
= "control/sysrq",
246 .callback
= sysrq_handler
250 static struct xenbus_watch shutdown_watch
= {
251 .node
= "control/shutdown",
252 .callback
= shutdown_handler
255 static int setup_shutdown_watcher(void)
259 err
= register_xenbus_watch(&shutdown_watch
);
261 printk(KERN_ERR
"Failed to set shutdown watcher\n");
265 #ifdef CONFIG_MAGIC_SYSRQ
266 err
= register_xenbus_watch(&sysrq_watch
);
268 printk(KERN_ERR
"Failed to set sysrq watcher\n");
276 static int shutdown_event(struct notifier_block
*notifier
,
280 setup_shutdown_watcher();
284 static int __init
__setup_shutdown_event(void)
286 /* Delay initialization in the PV on HVM case */
287 if (xen_hvm_domain())
290 if (!xen_pv_domain())
293 return xen_setup_shutdown_event();
296 int xen_setup_shutdown_event(void)
298 static struct notifier_block xenstore_notifier
= {
299 .notifier_call
= shutdown_event
301 register_xenstore_notifier(&xenstore_notifier
);
305 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event
);
307 subsys_initcall(__setup_shutdown_event
);