sparc: properly conditionalize use of TIF_32BIT
[linux/fpc-iii.git] / drivers / xen / manage.c
blob5f1e1f3cd18619ed2899dcc5e967ca274f690189
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_timer_resume();
94 syscore_resume();
96 return 0;
99 static void do_suspend(void)
101 int err;
102 struct suspend_info si;
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
109 during suspend. */
110 err = freeze_processes();
111 if (err) {
112 pr_err("%s: freeze failed %d\n", __func__, err);
113 goto out;
115 #endif
117 err = dpm_suspend_start(PMSG_FREEZE);
118 if (err) {
119 pr_err("%s: dpm_suspend_start %d\n", __func__, err);
120 goto out_thaw;
123 printk(KERN_DEBUG "suspending xenstore...\n");
124 xs_suspend();
126 err = dpm_suspend_end(PMSG_FREEZE);
127 if (err) {
128 pr_err("dpm_suspend_end failed: %d\n", err);
129 si.cancelled = 0;
130 goto out_resume;
133 si.cancelled = 1;
135 err = stop_machine(xen_suspend, &si, cpumask_of(0));
137 /* Resume console as early as possible. */
138 if (!si.cancelled)
139 xen_console_resume();
141 raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
143 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
145 if (err) {
146 pr_err("failed to start xen_suspend: %d\n", err);
147 si.cancelled = 1;
150 out_resume:
151 if (!si.cancelled) {
152 xen_arch_resume();
153 xs_resume();
154 } else
155 xs_suspend_cancel();
157 dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
159 out_thaw:
160 #ifdef CONFIG_PREEMPT
161 thaw_processes();
162 out:
163 #endif
164 shutting_down = SHUTDOWN_INVALID;
166 #endif /* CONFIG_HIBERNATE_CALLBACKS */
168 struct shutdown_handler {
169 const char *command;
170 void (*cb)(void);
173 static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
175 switch (code) {
176 case SYS_DOWN:
177 case SYS_HALT:
178 case SYS_POWER_OFF:
179 shutting_down = SHUTDOWN_POWEROFF;
180 default:
181 break;
183 return NOTIFY_DONE;
185 static void do_poweroff(void)
187 switch (system_state) {
188 case SYSTEM_BOOTING:
189 orderly_poweroff(true);
190 break;
191 case SYSTEM_RUNNING:
192 orderly_poweroff(false);
193 break;
194 default:
195 /* Don't do it when we are halting/rebooting. */
196 pr_info("Ignoring Xen toolstack shutdown.\n");
197 break;
201 static void do_reboot(void)
203 shutting_down = SHUTDOWN_POWEROFF; /* ? */
204 ctrl_alt_del();
207 static void shutdown_handler(struct xenbus_watch *watch,
208 const char **vec, unsigned int len)
210 char *str;
211 struct xenbus_transaction xbt;
212 int err;
213 static struct shutdown_handler handlers[] = {
214 { "poweroff", do_poweroff },
215 { "halt", do_poweroff },
216 { "reboot", do_reboot },
217 #ifdef CONFIG_HIBERNATE_CALLBACKS
218 { "suspend", do_suspend },
219 #endif
220 {NULL, NULL},
222 static struct shutdown_handler *handler;
224 if (shutting_down != SHUTDOWN_INVALID)
225 return;
227 again:
228 err = xenbus_transaction_start(&xbt);
229 if (err)
230 return;
232 str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
233 /* Ignore read errors and empty reads. */
234 if (XENBUS_IS_ERR_READ(str)) {
235 xenbus_transaction_end(xbt, 1);
236 return;
239 for (handler = &handlers[0]; handler->command; handler++) {
240 if (strcmp(str, handler->command) == 0)
241 break;
244 /* Only acknowledge commands which we are prepared to handle. */
245 if (handler->cb)
246 xenbus_write(xbt, "control", "shutdown", "");
248 err = xenbus_transaction_end(xbt, 0);
249 if (err == -EAGAIN) {
250 kfree(str);
251 goto again;
254 if (handler->cb) {
255 handler->cb();
256 } else {
257 pr_info("Ignoring shutdown request: %s\n", str);
258 shutting_down = SHUTDOWN_INVALID;
261 kfree(str);
264 #ifdef CONFIG_MAGIC_SYSRQ
265 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
266 unsigned int len)
268 char sysrq_key = '\0';
269 struct xenbus_transaction xbt;
270 int err;
272 again:
273 err = xenbus_transaction_start(&xbt);
274 if (err)
275 return;
276 if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
277 pr_err("Unable to read sysrq code in control/sysrq\n");
278 xenbus_transaction_end(xbt, 1);
279 return;
282 if (sysrq_key != '\0')
283 xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
285 err = xenbus_transaction_end(xbt, 0);
286 if (err == -EAGAIN)
287 goto again;
289 if (sysrq_key != '\0')
290 handle_sysrq(sysrq_key);
293 static struct xenbus_watch sysrq_watch = {
294 .node = "control/sysrq",
295 .callback = sysrq_handler
297 #endif
299 static struct xenbus_watch shutdown_watch = {
300 .node = "control/shutdown",
301 .callback = shutdown_handler
304 static struct notifier_block xen_reboot_nb = {
305 .notifier_call = poweroff_nb,
308 static int setup_shutdown_watcher(void)
310 int err;
312 err = register_xenbus_watch(&shutdown_watch);
313 if (err) {
314 pr_err("Failed to set shutdown watcher\n");
315 return err;
319 #ifdef CONFIG_MAGIC_SYSRQ
320 err = register_xenbus_watch(&sysrq_watch);
321 if (err) {
322 pr_err("Failed to set sysrq watcher\n");
323 return err;
325 #endif
327 return 0;
330 static int shutdown_event(struct notifier_block *notifier,
331 unsigned long event,
332 void *data)
334 setup_shutdown_watcher();
335 return NOTIFY_DONE;
338 int xen_setup_shutdown_event(void)
340 static struct notifier_block xenstore_notifier = {
341 .notifier_call = shutdown_event
344 if (!xen_domain())
345 return -ENODEV;
346 register_xenstore_notifier(&xenstore_notifier);
347 register_reboot_notifier(&xen_reboot_nb);
349 return 0;
351 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
353 subsys_initcall(xen_setup_shutdown_event);