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
);
58 static int xen_suspend(void *data
)
61 int *cancelled
= data
;
63 BUG_ON(!irqs_disabled());
65 err
= sysdev_suspend(PMSG_SUSPEND
);
67 printk(KERN_ERR
"xen_suspend: sysdev_suspend failed: %d\n",
77 * This hypercall returns 1 if suspend was cancelled
78 * or the domain was merely checkpointed, and 0 if it
79 * is resuming in a new domain.
81 *cancelled
= HYPERVISOR_suspend(virt_to_mfn(xen_start_info
));
83 xen_post_suspend(*cancelled
);
98 static void do_suspend(void)
103 shutting_down
= SHUTDOWN_SUSPEND
;
105 #ifdef CONFIG_PREEMPT
106 /* If the kernel is preemptible, we need to freeze all the processes
107 to prevent them from being in the middle of a pagetable update
109 err
= freeze_processes();
111 printk(KERN_ERR
"xen suspend: freeze failed %d\n", err
);
116 err
= dpm_suspend_start(PMSG_SUSPEND
);
118 printk(KERN_ERR
"xen suspend: dpm_suspend_start %d\n", err
);
122 printk(KERN_DEBUG
"suspending xenstore...\n");
125 err
= dpm_suspend_noirq(PMSG_SUSPEND
);
127 printk(KERN_ERR
"dpm_suspend_noirq failed: %d\n", err
);
131 if (xen_hvm_domain())
132 err
= stop_machine(xen_hvm_suspend
, &cancelled
, cpumask_of(0));
134 err
= stop_machine(xen_suspend
, &cancelled
, cpumask_of(0));
136 dpm_resume_noirq(PMSG_RESUME
);
139 printk(KERN_ERR
"failed to start xen_suspend: %d\n", err
);
150 dpm_resume_end(PMSG_RESUME
);
152 /* Make sure timer events get retriggered on all CPUs */
156 #ifdef CONFIG_PREEMPT
160 shutting_down
= SHUTDOWN_INVALID
;
162 #endif /* CONFIG_PM_SLEEP */
164 static void shutdown_handler(struct xenbus_watch
*watch
,
165 const char **vec
, unsigned int len
)
168 struct xenbus_transaction xbt
;
171 if (shutting_down
!= SHUTDOWN_INVALID
)
175 err
= xenbus_transaction_start(&xbt
);
179 str
= (char *)xenbus_read(xbt
, "control", "shutdown", NULL
);
180 /* Ignore read errors and empty reads. */
181 if (XENBUS_IS_ERR_READ(str
)) {
182 xenbus_transaction_end(xbt
, 1);
186 xenbus_write(xbt
, "control", "shutdown", "");
188 err
= xenbus_transaction_end(xbt
, 0);
189 if (err
== -EAGAIN
) {
194 if (strcmp(str
, "poweroff") == 0 ||
195 strcmp(str
, "halt") == 0) {
196 shutting_down
= SHUTDOWN_POWEROFF
;
197 orderly_poweroff(false);
198 } else if (strcmp(str
, "reboot") == 0) {
199 shutting_down
= SHUTDOWN_POWEROFF
; /* ? */
201 #ifdef CONFIG_PM_SLEEP
202 } else if (strcmp(str
, "suspend") == 0) {
206 printk(KERN_INFO
"Ignoring shutdown request: %s\n", str
);
207 shutting_down
= SHUTDOWN_INVALID
;
213 #ifdef CONFIG_MAGIC_SYSRQ
214 static void sysrq_handler(struct xenbus_watch
*watch
, const char **vec
,
217 char sysrq_key
= '\0';
218 struct xenbus_transaction xbt
;
222 err
= xenbus_transaction_start(&xbt
);
225 if (!xenbus_scanf(xbt
, "control", "sysrq", "%c", &sysrq_key
)) {
226 printk(KERN_ERR
"Unable to read sysrq code in "
228 xenbus_transaction_end(xbt
, 1);
232 if (sysrq_key
!= '\0')
233 xenbus_printf(xbt
, "control", "sysrq", "%c", '\0');
235 err
= xenbus_transaction_end(xbt
, 0);
239 if (sysrq_key
!= '\0')
240 handle_sysrq(sysrq_key
);
243 static struct xenbus_watch sysrq_watch
= {
244 .node
= "control/sysrq",
245 .callback
= sysrq_handler
249 static struct xenbus_watch shutdown_watch
= {
250 .node
= "control/shutdown",
251 .callback
= shutdown_handler
254 static int setup_shutdown_watcher(void)
258 err
= register_xenbus_watch(&shutdown_watch
);
260 printk(KERN_ERR
"Failed to set shutdown watcher\n");
264 #ifdef CONFIG_MAGIC_SYSRQ
265 err
= register_xenbus_watch(&sysrq_watch
);
267 printk(KERN_ERR
"Failed to set sysrq watcher\n");
275 static int shutdown_event(struct notifier_block
*notifier
,
279 setup_shutdown_watcher();
283 static int __init
__setup_shutdown_event(void)
285 /* Delay initialization in the PV on HVM case */
286 if (xen_hvm_domain())
289 if (!xen_pv_domain())
292 return xen_setup_shutdown_event();
295 int xen_setup_shutdown_event(void)
297 static struct notifier_block xenstore_notifier
= {
298 .notifier_call
= shutdown_event
300 register_xenstore_notifier(&xenstore_notifier
);
304 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event
);
306 subsys_initcall(__setup_shutdown_event
);