crypto: qce - add dependancy to Kconfig
[linux-2.6/btrfs-unstable.git] / drivers / xen / manage.c
blobc3667b202f2f50618d85d147d86ac746535e3464
1 /*
2 * Handle extern requests for shutdown, reboot and sysrq
3 */
5 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
7 #include <linux/kernel.h>
8 #include <linux/err.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>
17 #include <xen/xen.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>
28 enum shutdown_state {
29 SHUTDOWN_INVALID = -1,
30 SHUTDOWN_POWEROFF = 0,
31 SHUTDOWN_SUSPEND = 2,
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. */
36 SHUTDOWN_HALT = 4,
39 /* Ignore multiple shutdown requests. */
40 static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
42 struct suspend_info {
43 int cancelled;
46 static RAW_NOTIFIER_HEAD(xen_resume_notifier);
48 void xen_resume_notifier_register(struct notifier_block *nb)
50 raw_notifier_chain_register(&xen_resume_notifier, nb);
52 EXPORT_SYMBOL_GPL(xen_resume_notifier_register);
54 void xen_resume_notifier_unregister(struct notifier_block *nb)
56 raw_notifier_chain_unregister(&xen_resume_notifier, nb);
58 EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
60 #ifdef CONFIG_HIBERNATE_CALLBACKS
61 static int xen_suspend(void *data)
63 struct suspend_info *si = data;
64 int err;
66 BUG_ON(!irqs_disabled());
68 err = syscore_suspend();
69 if (err) {
70 pr_err("%s: system core suspend failed: %d\n", __func__, err);
71 return err;
74 gnttab_suspend();
75 xen_arch_pre_suspend();
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 si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
83 ? virt_to_mfn(xen_start_info)
84 : 0);
86 xen_arch_post_suspend(si->cancelled);
87 gnttab_resume();
89 if (!si->cancelled) {
90 xen_irq_resume();
91 xen_console_resume();
92 xen_timer_resume();
95 syscore_resume();
97 return 0;
100 static void do_suspend(void)
102 int err;
103 struct suspend_info si;
105 shutting_down = SHUTDOWN_SUSPEND;
107 #ifdef CONFIG_PREEMPT
108 /* If the kernel is preemptible, we need to freeze all the processes
109 to prevent them from being in the middle of a pagetable update
110 during suspend. */
111 err = freeze_processes();
112 if (err) {
113 pr_err("%s: freeze failed %d\n", __func__, err);
114 goto out;
116 #endif
118 err = dpm_suspend_start(PMSG_FREEZE);
119 if (err) {
120 pr_err("%s: dpm_suspend_start %d\n", __func__, err);
121 goto out_thaw;
124 printk(KERN_DEBUG "suspending xenstore...\n");
125 xs_suspend();
127 err = dpm_suspend_end(PMSG_FREEZE);
128 if (err) {
129 pr_err("dpm_suspend_end failed: %d\n", err);
130 si.cancelled = 0;
131 goto out_resume;
134 si.cancelled = 1;
136 err = stop_machine(xen_suspend, &si, cpumask_of(0));
138 raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
140 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
142 if (err) {
143 pr_err("failed to start xen_suspend: %d\n", err);
144 si.cancelled = 1;
147 out_resume:
148 if (!si.cancelled) {
149 xen_arch_resume();
150 xs_resume();
151 } else
152 xs_suspend_cancel();
154 dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
156 out_thaw:
157 #ifdef CONFIG_PREEMPT
158 thaw_processes();
159 out:
160 #endif
161 shutting_down = SHUTDOWN_INVALID;
163 #endif /* CONFIG_HIBERNATE_CALLBACKS */
165 struct shutdown_handler {
166 const char *command;
167 void (*cb)(void);
170 static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
172 switch (code) {
173 case SYS_DOWN:
174 case SYS_HALT:
175 case SYS_POWER_OFF:
176 shutting_down = SHUTDOWN_POWEROFF;
177 default:
178 break;
180 return NOTIFY_DONE;
182 static void do_poweroff(void)
184 switch (system_state) {
185 case SYSTEM_BOOTING:
186 orderly_poweroff(true);
187 break;
188 case SYSTEM_RUNNING:
189 orderly_poweroff(false);
190 break;
191 default:
192 /* Don't do it when we are halting/rebooting. */
193 pr_info("Ignoring Xen toolstack shutdown.\n");
194 break;
198 static void do_reboot(void)
200 shutting_down = SHUTDOWN_POWEROFF; /* ? */
201 ctrl_alt_del();
204 static void shutdown_handler(struct xenbus_watch *watch,
205 const char **vec, unsigned int len)
207 char *str;
208 struct xenbus_transaction xbt;
209 int err;
210 static struct shutdown_handler handlers[] = {
211 { "poweroff", do_poweroff },
212 { "halt", do_poweroff },
213 { "reboot", do_reboot },
214 #ifdef CONFIG_HIBERNATE_CALLBACKS
215 { "suspend", do_suspend },
216 #endif
217 {NULL, NULL},
219 static struct shutdown_handler *handler;
221 if (shutting_down != SHUTDOWN_INVALID)
222 return;
224 again:
225 err = xenbus_transaction_start(&xbt);
226 if (err)
227 return;
229 str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
230 /* Ignore read errors and empty reads. */
231 if (XENBUS_IS_ERR_READ(str)) {
232 xenbus_transaction_end(xbt, 1);
233 return;
236 for (handler = &handlers[0]; handler->command; handler++) {
237 if (strcmp(str, handler->command) == 0)
238 break;
241 /* Only acknowledge commands which we are prepared to handle. */
242 if (handler->cb)
243 xenbus_write(xbt, "control", "shutdown", "");
245 err = xenbus_transaction_end(xbt, 0);
246 if (err == -EAGAIN) {
247 kfree(str);
248 goto again;
251 if (handler->cb) {
252 handler->cb();
253 } else {
254 pr_info("Ignoring shutdown request: %s\n", str);
255 shutting_down = SHUTDOWN_INVALID;
258 kfree(str);
261 #ifdef CONFIG_MAGIC_SYSRQ
262 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
263 unsigned int len)
265 char sysrq_key = '\0';
266 struct xenbus_transaction xbt;
267 int err;
269 again:
270 err = xenbus_transaction_start(&xbt);
271 if (err)
272 return;
273 if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
274 pr_err("Unable to read sysrq code in control/sysrq\n");
275 xenbus_transaction_end(xbt, 1);
276 return;
279 if (sysrq_key != '\0')
280 xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
282 err = xenbus_transaction_end(xbt, 0);
283 if (err == -EAGAIN)
284 goto again;
286 if (sysrq_key != '\0')
287 handle_sysrq(sysrq_key);
290 static struct xenbus_watch sysrq_watch = {
291 .node = "control/sysrq",
292 .callback = sysrq_handler
294 #endif
296 static struct xenbus_watch shutdown_watch = {
297 .node = "control/shutdown",
298 .callback = shutdown_handler
301 static struct notifier_block xen_reboot_nb = {
302 .notifier_call = poweroff_nb,
305 static int setup_shutdown_watcher(void)
307 int err;
309 err = register_xenbus_watch(&shutdown_watch);
310 if (err) {
311 pr_err("Failed to set shutdown watcher\n");
312 return err;
316 #ifdef CONFIG_MAGIC_SYSRQ
317 err = register_xenbus_watch(&sysrq_watch);
318 if (err) {
319 pr_err("Failed to set sysrq watcher\n");
320 return err;
322 #endif
324 return 0;
327 static int shutdown_event(struct notifier_block *notifier,
328 unsigned long event,
329 void *data)
331 setup_shutdown_watcher();
332 return NOTIFY_DONE;
335 int xen_setup_shutdown_event(void)
337 static struct notifier_block xenstore_notifier = {
338 .notifier_call = shutdown_event
341 if (!xen_domain())
342 return -ENODEV;
343 register_xenstore_notifier(&xenstore_notifier);
344 register_reboot_notifier(&xen_reboot_nb);
346 return 0;
348 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
350 subsys_initcall(xen_setup_shutdown_event);