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;
39 unsigned long arg; /* extra hypercall argument */
41 void (*post)(int cancelled);
44 static void xen_hvm_post_suspend(int cancelled)
46 xen_arch_hvm_post_suspend(cancelled);
50 static void xen_pre_suspend(void)
54 xen_arch_pre_suspend();
57 static void xen_post_suspend(int cancelled)
59 xen_arch_post_suspend(cancelled);
64 #ifdef CONFIG_PM_SLEEP
65 static int xen_hvm_suspend(void *data)
67 struct suspend_info *si = data;
70 BUG_ON(!irqs_disabled());
72 err = sysdev_suspend(PMSG_SUSPEND);
74 printk(KERN_ERR "xen_hvm_suspend: sysdev_suspend failed: %d\n",
83 * This hypercall returns 1 if suspend was cancelled
84 * or the domain was merely checkpointed, and 0 if it
85 * is resuming in a new domain.
87 si->cancelled = HYPERVISOR_suspend(si->arg);
90 si->post(si->cancelled);
103 static int xen_suspend(void *data)
105 struct suspend_info *si = data;
108 BUG_ON(!irqs_disabled());
110 err = sysdev_suspend(PMSG_SUSPEND);
112 printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
121 * This hypercall returns 1 if suspend was cancelled
122 * or the domain was merely checkpointed, and 0 if it
123 * is resuming in a new domain.
125 si->cancelled = HYPERVISOR_suspend(si->arg);
128 si->post(si->cancelled);
130 if (!si->cancelled) {
132 xen_console_resume();
141 static void do_suspend(void)
144 struct suspend_info si;
146 shutting_down = SHUTDOWN_SUSPEND;
148 #ifdef CONFIG_PREEMPT
149 /* If the kernel is preemptible, we need to freeze all the processes
150 to prevent them from being in the middle of a pagetable update
152 err = freeze_processes();
154 printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
159 err = dpm_suspend_start(PMSG_SUSPEND);
161 printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err);
165 printk(KERN_DEBUG "suspending xenstore...\n");
168 err = dpm_suspend_noirq(PMSG_SUSPEND);
170 printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
176 if (xen_hvm_domain()) {
179 si.post = &xen_hvm_post_suspend;
181 si.arg = virt_to_mfn(xen_start_info);
182 si.pre = &xen_pre_suspend;
183 si.post = &xen_post_suspend;
186 if (xen_hvm_domain())
187 err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0));
189 err = stop_machine(xen_suspend, &si, cpumask_of(0));
191 dpm_resume_noirq(PMSG_RESUME);
194 printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
205 dpm_resume_end(PMSG_RESUME);
207 /* Make sure timer events get retriggered on all CPUs */
211 #ifdef CONFIG_PREEMPT
215 shutting_down = SHUTDOWN_INVALID;
217 #endif /* CONFIG_PM_SLEEP */
219 struct shutdown_handler {
224 static void do_poweroff(void)
226 shutting_down = SHUTDOWN_POWEROFF;
227 orderly_poweroff(false);
230 static void do_reboot(void)
232 shutting_down = SHUTDOWN_POWEROFF; /* ? */
236 static void shutdown_handler(struct xenbus_watch *watch,
237 const char **vec, unsigned int len)
240 struct xenbus_transaction xbt;
242 static struct shutdown_handler handlers[] = {
243 { "poweroff", do_poweroff },
244 { "halt", do_poweroff },
245 { "reboot", do_reboot },
246 #ifdef CONFIG_PM_SLEEP
247 { "suspend", do_suspend },
251 static struct shutdown_handler *handler;
253 if (shutting_down != SHUTDOWN_INVALID)
257 err = xenbus_transaction_start(&xbt);
261 str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
262 /* Ignore read errors and empty reads. */
263 if (XENBUS_IS_ERR_READ(str)) {
264 xenbus_transaction_end(xbt, 1);
268 for (handler = &handlers[0]; handler->command; handler++) {
269 if (strcmp(str, handler->command) == 0)
273 /* Only acknowledge commands which we are prepared to handle. */
275 xenbus_write(xbt, "control", "shutdown", "");
277 err = xenbus_transaction_end(xbt, 0);
278 if (err == -EAGAIN) {
286 printk(KERN_INFO "Ignoring shutdown request: %s\n", str);
287 shutting_down = SHUTDOWN_INVALID;
293 #ifdef CONFIG_MAGIC_SYSRQ
294 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
297 char sysrq_key = '\0';
298 struct xenbus_transaction xbt;
302 err = xenbus_transaction_start(&xbt);
305 if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
306 printk(KERN_ERR "Unable to read sysrq code in "
308 xenbus_transaction_end(xbt, 1);
312 if (sysrq_key != '\0')
313 xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
315 err = xenbus_transaction_end(xbt, 0);
319 if (sysrq_key != '\0')
320 handle_sysrq(sysrq_key);
323 static struct xenbus_watch sysrq_watch = {
324 .node = "control/sysrq",
325 .callback = sysrq_handler
329 static struct xenbus_watch shutdown_watch = {
330 .node = "control/shutdown",
331 .callback = shutdown_handler
334 static int setup_shutdown_watcher(void)
338 err = register_xenbus_watch(&shutdown_watch);
340 printk(KERN_ERR "Failed to set shutdown watcher\n");
344 #ifdef CONFIG_MAGIC_SYSRQ
345 err = register_xenbus_watch(&sysrq_watch);
347 printk(KERN_ERR "Failed to set sysrq watcher\n");
355 static int shutdown_event(struct notifier_block *notifier,
359 setup_shutdown_watcher();
363 int xen_setup_shutdown_event(void)
365 static struct notifier_block xenstore_notifier = {
366 .notifier_call = shutdown_event
371 register_xenstore_notifier(&xenstore_notifier);
375 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
377 subsys_initcall(xen_setup_shutdown_event);