cd046684e0d1bb7e6e3e7330e402ec65bbf2f5d5
[linux-2.6-microblaze.git] / drivers / xen / manage.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Handle extern requests for shutdown, reboot and sysrq
4  */
5
6 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
7
8 #include <linux/kernel.h>
9 #include <linux/err.h>
10 #include <linux/slab.h>
11 #include <linux/reboot.h>
12 #include <linux/sysrq.h>
13 #include <linux/stop_machine.h>
14 #include <linux/freezer.h>
15 #include <linux/syscore_ops.h>
16 #include <linux/export.h>
17
18 #include <xen/xen.h>
19 #include <xen/xenbus.h>
20 #include <xen/grant_table.h>
21 #include <xen/events.h>
22 #include <xen/hvc-console.h>
23 #include <xen/page.h>
24 #include <xen/xen-ops.h>
25
26 #include <asm/xen/hypercall.h>
27 #include <asm/xen/hypervisor.h>
28
29 enum shutdown_state {
30         SHUTDOWN_INVALID = -1,
31         SHUTDOWN_POWEROFF = 0,
32         SHUTDOWN_SUSPEND = 2,
33         /* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
34            report a crash, not be instructed to crash!
35            HALT is the same as POWEROFF, as far as we're concerned.  The tools use
36            the distinction when we return the reason code to them.  */
37          SHUTDOWN_HALT = 4,
38 };
39
40 /* Ignore multiple shutdown requests. */
41 static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
42
43 struct suspend_info {
44         int cancelled;
45 };
46
47 static RAW_NOTIFIER_HEAD(xen_resume_notifier);
48
49 void xen_resume_notifier_register(struct notifier_block *nb)
50 {
51         raw_notifier_chain_register(&xen_resume_notifier, nb);
52 }
53 EXPORT_SYMBOL_GPL(xen_resume_notifier_register);
54
55 void xen_resume_notifier_unregister(struct notifier_block *nb)
56 {
57         raw_notifier_chain_unregister(&xen_resume_notifier, nb);
58 }
59 EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
60
61 #ifdef CONFIG_HIBERNATE_CALLBACKS
62 static int xen_suspend(void *data)
63 {
64         struct suspend_info *si = data;
65         int err;
66
67         BUG_ON(!irqs_disabled());
68
69         err = syscore_suspend();
70         if (err) {
71                 pr_err("%s: system core suspend failed: %d\n", __func__, err);
72                 return err;
73         }
74
75         gnttab_suspend();
76         xen_manage_runstate_time(-1);
77         xen_arch_pre_suspend();
78
79         si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
80                                            ? virt_to_gfn(xen_start_info)
81                                            : 0);
82
83         xen_arch_post_suspend(si->cancelled);
84         xen_manage_runstate_time(si->cancelled ? 1 : 0);
85         gnttab_resume();
86
87         if (!si->cancelled) {
88                 xen_irq_resume();
89                 xen_timer_resume();
90         }
91
92         syscore_resume();
93
94         return 0;
95 }
96
97 static void do_suspend(void)
98 {
99         int err;
100         struct suspend_info si;
101
102         shutting_down = SHUTDOWN_SUSPEND;
103
104         err = freeze_processes();
105         if (err) {
106                 pr_err("%s: freeze processes failed %d\n", __func__, err);
107                 goto out;
108         }
109
110         err = freeze_kernel_threads();
111         if (err) {
112                 pr_err("%s: freeze kernel threads failed %d\n", __func__, err);
113                 goto out_thaw;
114         }
115
116         err = dpm_suspend_start(PMSG_FREEZE);
117         if (err) {
118                 pr_err("%s: dpm_suspend_start %d\n", __func__, err);
119                 goto out_thaw;
120         }
121
122         printk(KERN_DEBUG "suspending xenstore...\n");
123         xs_suspend();
124
125         err = dpm_suspend_end(PMSG_FREEZE);
126         if (err) {
127                 pr_err("dpm_suspend_end failed: %d\n", err);
128                 si.cancelled = 0;
129                 goto out_resume;
130         }
131
132         xen_arch_suspend();
133
134         si.cancelled = 1;
135
136         err = stop_machine(xen_suspend, &si, cpumask_of(0));
137
138         /* Resume console as early as possible. */
139         if (!si.cancelled)
140                 xen_console_resume();
141
142         raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
143
144         dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
145
146         if (err) {
147                 pr_err("failed to start xen_suspend: %d\n", err);
148                 si.cancelled = 1;
149         }
150
151         xen_arch_resume();
152
153 out_resume:
154         if (!si.cancelled)
155                 xs_resume();
156         else
157                 xs_suspend_cancel();
158
159         dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
160
161 out_thaw:
162         thaw_processes();
163 out:
164         shutting_down = SHUTDOWN_INVALID;
165 }
166 #endif  /* CONFIG_HIBERNATE_CALLBACKS */
167
168 struct shutdown_handler {
169 #define SHUTDOWN_CMD_SIZE 11
170         const char command[SHUTDOWN_CMD_SIZE];
171         bool flag;
172         void (*cb)(void);
173 };
174
175 static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
176 {
177         switch (code) {
178         case SYS_DOWN:
179         case SYS_HALT:
180         case SYS_POWER_OFF:
181                 shutting_down = SHUTDOWN_POWEROFF;
182         default:
183                 break;
184         }
185         return NOTIFY_DONE;
186 }
187 static void do_poweroff(void)
188 {
189         switch (system_state) {
190         case SYSTEM_BOOTING:
191         case SYSTEM_SCHEDULING:
192                 orderly_poweroff(true);
193                 break;
194         case SYSTEM_RUNNING:
195                 orderly_poweroff(false);
196                 break;
197         default:
198                 /* Don't do it when we are halting/rebooting. */
199                 pr_info("Ignoring Xen toolstack shutdown.\n");
200                 break;
201         }
202 }
203
204 static void do_reboot(void)
205 {
206         shutting_down = SHUTDOWN_POWEROFF; /* ? */
207         ctrl_alt_del();
208 }
209
210 static struct shutdown_handler shutdown_handlers[] = {
211         { "poweroff",   true,   do_poweroff },
212         { "halt",       false,  do_poweroff },
213         { "reboot",     true,   do_reboot   },
214 #ifdef CONFIG_HIBERNATE_CALLBACKS
215         { "suspend",    true,   do_suspend  },
216 #endif
217 };
218
219 static void shutdown_handler(struct xenbus_watch *watch,
220                              const char *path, const char *token)
221 {
222         char *str;
223         struct xenbus_transaction xbt;
224         int err;
225         int idx;
226
227         if (shutting_down != SHUTDOWN_INVALID)
228                 return;
229
230  again:
231         err = xenbus_transaction_start(&xbt);
232         if (err)
233                 return;
234
235         str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
236         /* Ignore read errors and empty reads. */
237         if (XENBUS_IS_ERR_READ(str)) {
238                 xenbus_transaction_end(xbt, 1);
239                 return;
240         }
241
242         for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
243                 if (strcmp(str, shutdown_handlers[idx].command) == 0)
244                         break;
245         }
246
247         /* Only acknowledge commands which we are prepared to handle. */
248         if (idx < ARRAY_SIZE(shutdown_handlers))
249                 xenbus_write(xbt, "control", "shutdown", "");
250
251         err = xenbus_transaction_end(xbt, 0);
252         if (err == -EAGAIN) {
253                 kfree(str);
254                 goto again;
255         }
256
257         if (idx < ARRAY_SIZE(shutdown_handlers)) {
258                 shutdown_handlers[idx].cb();
259         } else {
260                 pr_info("Ignoring shutdown request: %s\n", str);
261                 shutting_down = SHUTDOWN_INVALID;
262         }
263
264         kfree(str);
265 }
266
267 #ifdef CONFIG_MAGIC_SYSRQ
268 static void sysrq_handler(struct xenbus_watch *watch, const char *path,
269                           const char *token)
270 {
271         char sysrq_key = '\0';
272         struct xenbus_transaction xbt;
273         int err;
274
275  again:
276         err = xenbus_transaction_start(&xbt);
277         if (err)
278                 return;
279         err = xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key);
280         if (err < 0) {
281                 /*
282                  * The Xenstore watch fires directly after registering it and
283                  * after a suspend/resume cycle. So ENOENT is no error but
284                  * might happen in those cases. ERANGE is observed when we get
285                  * an empty value (''), this happens when we acknowledge the
286                  * request by writing '\0' below.
287                  */
288                 if (err != -ENOENT && err != -ERANGE)
289                         pr_err("Error %d reading sysrq code in control/sysrq\n",
290                                err);
291                 xenbus_transaction_end(xbt, 1);
292                 return;
293         }
294
295         if (sysrq_key != '\0') {
296                 err = xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
297                 if (err) {
298                         pr_err("%s: Error %d writing sysrq in control/sysrq\n",
299                                __func__, err);
300                         xenbus_transaction_end(xbt, 1);
301                         return;
302                 }
303         }
304
305         err = xenbus_transaction_end(xbt, 0);
306         if (err == -EAGAIN)
307                 goto again;
308
309         if (sysrq_key != '\0')
310                 handle_sysrq(sysrq_key);
311 }
312
313 static struct xenbus_watch sysrq_watch = {
314         .node = "control/sysrq",
315         .callback = sysrq_handler
316 };
317 #endif
318
319 static struct xenbus_watch shutdown_watch = {
320         .node = "control/shutdown",
321         .callback = shutdown_handler
322 };
323
324 static struct notifier_block xen_reboot_nb = {
325         .notifier_call = poweroff_nb,
326 };
327
328 static int setup_shutdown_watcher(void)
329 {
330         int err;
331         int idx;
332 #define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
333         char node[FEATURE_PATH_SIZE];
334
335         err = register_xenbus_watch(&shutdown_watch);
336         if (err) {
337                 pr_err("Failed to set shutdown watcher\n");
338                 return err;
339         }
340
341
342 #ifdef CONFIG_MAGIC_SYSRQ
343         err = register_xenbus_watch(&sysrq_watch);
344         if (err) {
345                 pr_err("Failed to set sysrq watcher\n");
346                 return err;
347         }
348 #endif
349
350         for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
351                 if (!shutdown_handlers[idx].flag)
352                         continue;
353                 snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
354                          shutdown_handlers[idx].command);
355                 err = xenbus_printf(XBT_NIL, "control", node, "%u", 1);
356                 if (err) {
357                         pr_err("%s: Error %d writing %s\n", __func__,
358                                 err, node);
359                         return err;
360                 }
361         }
362
363         return 0;
364 }
365
366 static int shutdown_event(struct notifier_block *notifier,
367                           unsigned long event,
368                           void *data)
369 {
370         setup_shutdown_watcher();
371         return NOTIFY_DONE;
372 }
373
374 int xen_setup_shutdown_event(void)
375 {
376         static struct notifier_block xenstore_notifier = {
377                 .notifier_call = shutdown_event
378         };
379
380         if (!xen_domain())
381                 return -ENODEV;
382         register_xenstore_notifier(&xenstore_notifier);
383         register_reboot_notifier(&xen_reboot_nb);
384
385         return 0;
386 }
387 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
388
389 subsys_initcall(xen_setup_shutdown_event);