Merge tag 'driver-core-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / xen / manage.c
1 /*
2  * Handle extern requests for shutdown, reboot and sysrq
3  */
4
5 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
6
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>
16
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/page.h>
23 #include <xen/xen-ops.h>
24
25 #include <asm/xen/hypercall.h>
26 #include <asm/xen/hypervisor.h>
27
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,
37 };
38
39 /* Ignore multiple shutdown requests. */
40 static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
41
42 struct suspend_info {
43         int cancelled;
44 };
45
46 static RAW_NOTIFIER_HEAD(xen_resume_notifier);
47
48 void xen_resume_notifier_register(struct notifier_block *nb)
49 {
50         raw_notifier_chain_register(&xen_resume_notifier, nb);
51 }
52 EXPORT_SYMBOL_GPL(xen_resume_notifier_register);
53
54 void xen_resume_notifier_unregister(struct notifier_block *nb)
55 {
56         raw_notifier_chain_unregister(&xen_resume_notifier, nb);
57 }
58 EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
59
60 #ifdef CONFIG_HIBERNATE_CALLBACKS
61 static int xen_suspend(void *data)
62 {
63         struct suspend_info *si = data;
64         int err;
65
66         BUG_ON(!irqs_disabled());
67
68         err = syscore_suspend();
69         if (err) {
70                 pr_err("%s: system core suspend failed: %d\n", __func__, err);
71                 return err;
72         }
73
74         gnttab_suspend();
75         xen_arch_pre_suspend();
76
77         /*
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.
81          */
82         si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
83                                            ? virt_to_gfn(xen_start_info)
84                                            : 0);
85
86         xen_arch_post_suspend(si->cancelled);
87         gnttab_resume();
88
89         if (!si->cancelled) {
90                 xen_irq_resume();
91                 xen_timer_resume();
92         }
93
94         syscore_resume();
95
96         return 0;
97 }
98
99 static void do_suspend(void)
100 {
101         int err;
102         struct suspend_info si;
103
104         shutting_down = SHUTDOWN_SUSPEND;
105
106         err = freeze_processes();
107         if (err) {
108                 pr_err("%s: freeze processes failed %d\n", __func__, err);
109                 goto out;
110         }
111
112         err = freeze_kernel_threads();
113         if (err) {
114                 pr_err("%s: freeze kernel threads failed %d\n", __func__, err);
115                 goto out_thaw;
116         }
117
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;
122         }
123
124         printk(KERN_DEBUG "suspending xenstore...\n");
125         xs_suspend();
126
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;
132         }
133
134         xen_arch_suspend();
135
136         si.cancelled = 1;
137
138         err = stop_machine(xen_suspend, &si, cpumask_of(0));
139
140         /* Resume console as early as possible. */
141         if (!si.cancelled)
142                 xen_console_resume();
143
144         raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
145
146         dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
147
148         if (err) {
149                 pr_err("failed to start xen_suspend: %d\n", err);
150                 si.cancelled = 1;
151         }
152
153         xen_arch_resume();
154
155 out_resume:
156         if (!si.cancelled)
157                 xs_resume();
158         else
159                 xs_suspend_cancel();
160
161         dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
162
163 out_thaw:
164         thaw_processes();
165 out:
166         shutting_down = SHUTDOWN_INVALID;
167 }
168 #endif  /* CONFIG_HIBERNATE_CALLBACKS */
169
170 struct shutdown_handler {
171 #define SHUTDOWN_CMD_SIZE 11
172         const char command[SHUTDOWN_CMD_SIZE];
173         bool flag;
174         void (*cb)(void);
175 };
176
177 static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
178 {
179         switch (code) {
180         case SYS_DOWN:
181         case SYS_HALT:
182         case SYS_POWER_OFF:
183                 shutting_down = SHUTDOWN_POWEROFF;
184         default:
185                 break;
186         }
187         return NOTIFY_DONE;
188 }
189 static void do_poweroff(void)
190 {
191         switch (system_state) {
192         case SYSTEM_BOOTING:
193                 orderly_poweroff(true);
194                 break;
195         case SYSTEM_RUNNING:
196                 orderly_poweroff(false);
197                 break;
198         default:
199                 /* Don't do it when we are halting/rebooting. */
200                 pr_info("Ignoring Xen toolstack shutdown.\n");
201                 break;
202         }
203 }
204
205 static void do_reboot(void)
206 {
207         shutting_down = SHUTDOWN_POWEROFF; /* ? */
208         ctrl_alt_del();
209 }
210
211 static struct shutdown_handler shutdown_handlers[] = {
212         { "poweroff",   true,   do_poweroff },
213         { "halt",       false,  do_poweroff },
214         { "reboot",     true,   do_reboot   },
215 #ifdef CONFIG_HIBERNATE_CALLBACKS
216         { "suspend",    true,   do_suspend  },
217 #endif
218 };
219
220 static void shutdown_handler(struct xenbus_watch *watch,
221                              const char **vec, unsigned int len)
222 {
223         char *str;
224         struct xenbus_transaction xbt;
225         int err;
226         int idx;
227
228         if (shutting_down != SHUTDOWN_INVALID)
229                 return;
230
231  again:
232         err = xenbus_transaction_start(&xbt);
233         if (err)
234                 return;
235
236         str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
237         /* Ignore read errors and empty reads. */
238         if (XENBUS_IS_ERR_READ(str)) {
239                 xenbus_transaction_end(xbt, 1);
240                 return;
241         }
242
243         for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
244                 if (strcmp(str, shutdown_handlers[idx].command) == 0)
245                         break;
246         }
247
248         /* Only acknowledge commands which we are prepared to handle. */
249         if (idx < ARRAY_SIZE(shutdown_handlers))
250                 xenbus_write(xbt, "control", "shutdown", "");
251
252         err = xenbus_transaction_end(xbt, 0);
253         if (err == -EAGAIN) {
254                 kfree(str);
255                 goto again;
256         }
257
258         if (idx < ARRAY_SIZE(shutdown_handlers)) {
259                 shutdown_handlers[idx].cb();
260         } else {
261                 pr_info("Ignoring shutdown request: %s\n", str);
262                 shutting_down = SHUTDOWN_INVALID;
263         }
264
265         kfree(str);
266 }
267
268 #ifdef CONFIG_MAGIC_SYSRQ
269 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
270                           unsigned int len)
271 {
272         char sysrq_key = '\0';
273         struct xenbus_transaction xbt;
274         int err;
275
276  again:
277         err = xenbus_transaction_start(&xbt);
278         if (err)
279                 return;
280         if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
281                 pr_err("Unable to read sysrq code in control/sysrq\n");
282                 xenbus_transaction_end(xbt, 1);
283                 return;
284         }
285
286         if (sysrq_key != '\0')
287                 xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
288
289         err = xenbus_transaction_end(xbt, 0);
290         if (err == -EAGAIN)
291                 goto again;
292
293         if (sysrq_key != '\0')
294                 handle_sysrq(sysrq_key);
295 }
296
297 static struct xenbus_watch sysrq_watch = {
298         .node = "control/sysrq",
299         .callback = sysrq_handler
300 };
301 #endif
302
303 static struct xenbus_watch shutdown_watch = {
304         .node = "control/shutdown",
305         .callback = shutdown_handler
306 };
307
308 static struct notifier_block xen_reboot_nb = {
309         .notifier_call = poweroff_nb,
310 };
311
312 static int setup_shutdown_watcher(void)
313 {
314         int err;
315         int idx;
316 #define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
317         char node[FEATURE_PATH_SIZE];
318
319         err = register_xenbus_watch(&shutdown_watch);
320         if (err) {
321                 pr_err("Failed to set shutdown watcher\n");
322                 return err;
323         }
324
325
326 #ifdef CONFIG_MAGIC_SYSRQ
327         err = register_xenbus_watch(&sysrq_watch);
328         if (err) {
329                 pr_err("Failed to set sysrq watcher\n");
330                 return err;
331         }
332 #endif
333
334         for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
335                 if (!shutdown_handlers[idx].flag)
336                         continue;
337                 snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
338                          shutdown_handlers[idx].command);
339                 xenbus_printf(XBT_NIL, "control", node, "%u", 1);
340         }
341
342         return 0;
343 }
344
345 static int shutdown_event(struct notifier_block *notifier,
346                           unsigned long event,
347                           void *data)
348 {
349         setup_shutdown_watcher();
350         return NOTIFY_DONE;
351 }
352
353 int xen_setup_shutdown_event(void)
354 {
355         static struct notifier_block xenstore_notifier = {
356                 .notifier_call = shutdown_event
357         };
358
359         if (!xen_domain())
360                 return -ENODEV;
361         register_xenstore_notifier(&xenstore_notifier);
362         register_reboot_notifier(&xen_reboot_nb);
363
364         return 0;
365 }
366 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
367
368 subsys_initcall(xen_setup_shutdown_event);