2 * Handle extern requests for shutdown, reboot and sysrq
5 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
7 #include <linux/kernel.h>
9 #include <linux/slab.h>
10 #include <linux/reboot.h>
11 #include <linux/sysrq.h>
12 #include <linux/stop_machine.h>
13 #include <linux/freezer.h>
14 #include <linux/syscore_ops.h>
15 #include <linux/export.h>
18 #include <xen/xenbus.h>
19 #include <xen/grant_table.h>
20 #include <xen/events.h>
21 #include <xen/hvc-console.h>
22 #include <xen/xen-ops.h>
24 #include <asm/xen/hypercall.h>
25 #include <asm/xen/page.h>
26 #include <asm/xen/hypervisor.h>
29 SHUTDOWN_INVALID = -1,
30 SHUTDOWN_POWEROFF = 0,
32 /* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
33 report a crash, not be instructed to crash!
34 HALT is the same as POWEROFF, as far as we're concerned. The tools use
35 the distinction when we return the reason code to them. */
39 /* Ignore multiple shutdown requests. */
40 static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
44 unsigned long arg; /* extra hypercall argument */
46 void (*post)(int cancelled);
49 #ifdef CONFIG_HIBERNATE_CALLBACKS
50 static void xen_hvm_post_suspend(int cancelled)
52 xen_arch_hvm_post_suspend(cancelled);
56 static void xen_pre_suspend(void)
60 xen_arch_pre_suspend();
63 static void xen_post_suspend(int cancelled)
65 xen_arch_post_suspend(cancelled);
70 static int xen_suspend(void *data)
72 struct suspend_info *si = data;
75 BUG_ON(!irqs_disabled());
77 err = syscore_suspend();
79 pr_err("%s: system core suspend failed: %d\n", __func__, err);
87 * This hypercall returns 1 if suspend was cancelled
88 * or the domain was merely checkpointed, and 0 if it
89 * is resuming in a new domain.
91 si->cancelled = HYPERVISOR_suspend(si->arg);
94 si->post(si->cancelled);
107 static void do_suspend(void)
110 struct suspend_info si;
112 shutting_down = SHUTDOWN_SUSPEND;
114 err = freeze_processes();
116 pr_err("%s: freeze failed %d\n", __func__, err);
120 err = dpm_suspend_start(PMSG_FREEZE);
122 pr_err("%s: dpm_suspend_start %d\n", __func__, err);
126 printk(KERN_DEBUG "suspending xenstore...\n");
129 err = dpm_suspend_end(PMSG_FREEZE);
131 pr_err("dpm_suspend_end failed: %d\n", err);
138 if (xen_hvm_domain()) {
141 si.post = &xen_hvm_post_suspend;
143 si.arg = virt_to_mfn(xen_start_info);
144 si.pre = &xen_pre_suspend;
145 si.post = &xen_post_suspend;
148 err = stop_machine(xen_suspend, &si, cpumask_of(0));
150 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
153 pr_err("failed to start xen_suspend: %d\n", err);
164 dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
169 shutting_down = SHUTDOWN_INVALID;
171 #endif /* CONFIG_HIBERNATE_CALLBACKS */
173 struct shutdown_handler {
178 static void do_poweroff(void)
180 shutting_down = SHUTDOWN_POWEROFF;
181 orderly_poweroff(false);
184 static void do_reboot(void)
186 shutting_down = SHUTDOWN_POWEROFF; /* ? */
190 static void shutdown_handler(struct xenbus_watch *watch,
191 const char **vec, unsigned int len)
194 struct xenbus_transaction xbt;
196 static struct shutdown_handler handlers[] = {
197 { "poweroff", do_poweroff },
198 { "halt", do_poweroff },
199 { "reboot", do_reboot },
200 #ifdef CONFIG_HIBERNATE_CALLBACKS
201 { "suspend", do_suspend },
205 static struct shutdown_handler *handler;
207 if (shutting_down != SHUTDOWN_INVALID)
211 err = xenbus_transaction_start(&xbt);
215 str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
216 /* Ignore read errors and empty reads. */
217 if (XENBUS_IS_ERR_READ(str)) {
218 xenbus_transaction_end(xbt, 1);
222 for (handler = &handlers[0]; handler->command; handler++) {
223 if (strcmp(str, handler->command) == 0)
227 /* Only acknowledge commands which we are prepared to handle. */
229 xenbus_write(xbt, "control", "shutdown", "");
231 err = xenbus_transaction_end(xbt, 0);
232 if (err == -EAGAIN) {
240 pr_info("Ignoring shutdown request: %s\n", str);
241 shutting_down = SHUTDOWN_INVALID;
247 #ifdef CONFIG_MAGIC_SYSRQ
248 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
251 char sysrq_key = '\0';
252 struct xenbus_transaction xbt;
256 err = xenbus_transaction_start(&xbt);
259 if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
260 pr_err("Unable to read sysrq code in control/sysrq\n");
261 xenbus_transaction_end(xbt, 1);
265 if (sysrq_key != '\0')
266 xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
268 err = xenbus_transaction_end(xbt, 0);
272 if (sysrq_key != '\0')
273 handle_sysrq(sysrq_key);
276 static struct xenbus_watch sysrq_watch = {
277 .node = "control/sysrq",
278 .callback = sysrq_handler
282 static struct xenbus_watch shutdown_watch = {
283 .node = "control/shutdown",
284 .callback = shutdown_handler
287 static int setup_shutdown_watcher(void)
291 err = register_xenbus_watch(&shutdown_watch);
293 pr_err("Failed to set shutdown watcher\n");
297 #ifdef CONFIG_MAGIC_SYSRQ
298 err = register_xenbus_watch(&sysrq_watch);
300 pr_err("Failed to set sysrq watcher\n");
308 static int shutdown_event(struct notifier_block *notifier,
312 setup_shutdown_watcher();
316 int xen_setup_shutdown_event(void)
318 static struct notifier_block xenstore_notifier = {
319 .notifier_call = shutdown_event
324 register_xenstore_notifier(&xenstore_notifier);
328 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
330 subsys_initcall(xen_setup_shutdown_event);