xref: /openbmc/linux/drivers/xen/manage.c (revision 8bd1369b)
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_manage_runstate_time(-1);
76 	xen_arch_pre_suspend();
77 
78 	si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
79                                            ? virt_to_gfn(xen_start_info)
80                                            : 0);
81 
82 	xen_arch_post_suspend(si->cancelled);
83 	xen_manage_runstate_time(si->cancelled ? 1 : 0);
84 	gnttab_resume();
85 
86 	if (!si->cancelled) {
87 		xen_irq_resume();
88 		xen_timer_resume();
89 	}
90 
91 	syscore_resume();
92 
93 	return 0;
94 }
95 
96 static void do_suspend(void)
97 {
98 	int err;
99 	struct suspend_info si;
100 
101 	shutting_down = SHUTDOWN_SUSPEND;
102 
103 	err = freeze_processes();
104 	if (err) {
105 		pr_err("%s: freeze processes failed %d\n", __func__, err);
106 		goto out;
107 	}
108 
109 	err = freeze_kernel_threads();
110 	if (err) {
111 		pr_err("%s: freeze kernel threads failed %d\n", __func__, err);
112 		goto out_thaw;
113 	}
114 
115 	err = dpm_suspend_start(PMSG_FREEZE);
116 	if (err) {
117 		pr_err("%s: dpm_suspend_start %d\n", __func__, err);
118 		goto out_thaw;
119 	}
120 
121 	printk(KERN_DEBUG "suspending xenstore...\n");
122 	xs_suspend();
123 
124 	err = dpm_suspend_end(PMSG_FREEZE);
125 	if (err) {
126 		pr_err("dpm_suspend_end failed: %d\n", err);
127 		si.cancelled = 0;
128 		goto out_resume;
129 	}
130 
131 	xen_arch_suspend();
132 
133 	si.cancelled = 1;
134 
135 	err = stop_machine(xen_suspend, &si, cpumask_of(0));
136 
137 	/* Resume console as early as possible. */
138 	if (!si.cancelled)
139 		xen_console_resume();
140 
141 	raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
142 
143 	dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
144 
145 	if (err) {
146 		pr_err("failed to start xen_suspend: %d\n", err);
147 		si.cancelled = 1;
148 	}
149 
150 	xen_arch_resume();
151 
152 out_resume:
153 	if (!si.cancelled)
154 		xs_resume();
155 	else
156 		xs_suspend_cancel();
157 
158 	dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
159 
160 out_thaw:
161 	thaw_processes();
162 out:
163 	shutting_down = SHUTDOWN_INVALID;
164 }
165 #endif	/* CONFIG_HIBERNATE_CALLBACKS */
166 
167 struct shutdown_handler {
168 #define SHUTDOWN_CMD_SIZE 11
169 	const char command[SHUTDOWN_CMD_SIZE];
170 	bool flag;
171 	void (*cb)(void);
172 };
173 
174 static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
175 {
176 	switch (code) {
177 	case SYS_DOWN:
178 	case SYS_HALT:
179 	case SYS_POWER_OFF:
180 		shutting_down = SHUTDOWN_POWEROFF;
181 	default:
182 		break;
183 	}
184 	return NOTIFY_DONE;
185 }
186 static void do_poweroff(void)
187 {
188 	switch (system_state) {
189 	case SYSTEM_BOOTING:
190 	case SYSTEM_SCHEDULING:
191 		orderly_poweroff(true);
192 		break;
193 	case SYSTEM_RUNNING:
194 		orderly_poweroff(false);
195 		break;
196 	default:
197 		/* Don't do it when we are halting/rebooting. */
198 		pr_info("Ignoring Xen toolstack shutdown.\n");
199 		break;
200 	}
201 }
202 
203 static void do_reboot(void)
204 {
205 	shutting_down = SHUTDOWN_POWEROFF; /* ? */
206 	ctrl_alt_del();
207 }
208 
209 static struct shutdown_handler shutdown_handlers[] = {
210 	{ "poweroff",	true,	do_poweroff },
211 	{ "halt",	false,	do_poweroff },
212 	{ "reboot",	true,	do_reboot   },
213 #ifdef CONFIG_HIBERNATE_CALLBACKS
214 	{ "suspend",	true,	do_suspend  },
215 #endif
216 };
217 
218 static void shutdown_handler(struct xenbus_watch *watch,
219 			     const char *path, const char *token)
220 {
221 	char *str;
222 	struct xenbus_transaction xbt;
223 	int err;
224 	int idx;
225 
226 	if (shutting_down != SHUTDOWN_INVALID)
227 		return;
228 
229  again:
230 	err = xenbus_transaction_start(&xbt);
231 	if (err)
232 		return;
233 
234 	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
235 	/* Ignore read errors and empty reads. */
236 	if (XENBUS_IS_ERR_READ(str)) {
237 		xenbus_transaction_end(xbt, 1);
238 		return;
239 	}
240 
241 	for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
242 		if (strcmp(str, shutdown_handlers[idx].command) == 0)
243 			break;
244 	}
245 
246 	/* Only acknowledge commands which we are prepared to handle. */
247 	if (idx < ARRAY_SIZE(shutdown_handlers))
248 		xenbus_write(xbt, "control", "shutdown", "");
249 
250 	err = xenbus_transaction_end(xbt, 0);
251 	if (err == -EAGAIN) {
252 		kfree(str);
253 		goto again;
254 	}
255 
256 	if (idx < ARRAY_SIZE(shutdown_handlers)) {
257 		shutdown_handlers[idx].cb();
258 	} else {
259 		pr_info("Ignoring shutdown request: %s\n", str);
260 		shutting_down = SHUTDOWN_INVALID;
261 	}
262 
263 	kfree(str);
264 }
265 
266 #ifdef CONFIG_MAGIC_SYSRQ
267 static void sysrq_handler(struct xenbus_watch *watch, const char *path,
268 			  const char *token)
269 {
270 	char sysrq_key = '\0';
271 	struct xenbus_transaction xbt;
272 	int err;
273 
274  again:
275 	err = xenbus_transaction_start(&xbt);
276 	if (err)
277 		return;
278 	err = xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key);
279 	if (err < 0) {
280 		/*
281 		 * The Xenstore watch fires directly after registering it and
282 		 * after a suspend/resume cycle. So ENOENT is no error but
283 		 * might happen in those cases.
284 		 */
285 		if (err != -ENOENT)
286 			pr_err("Error %d reading sysrq code in control/sysrq\n",
287 			       err);
288 		xenbus_transaction_end(xbt, 1);
289 		return;
290 	}
291 
292 	if (sysrq_key != '\0') {
293 		err = xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
294 		if (err) {
295 			pr_err("%s: Error %d writing sysrq in control/sysrq\n",
296 			       __func__, err);
297 			xenbus_transaction_end(xbt, 1);
298 			return;
299 		}
300 	}
301 
302 	err = xenbus_transaction_end(xbt, 0);
303 	if (err == -EAGAIN)
304 		goto again;
305 
306 	if (sysrq_key != '\0')
307 		handle_sysrq(sysrq_key);
308 }
309 
310 static struct xenbus_watch sysrq_watch = {
311 	.node = "control/sysrq",
312 	.callback = sysrq_handler
313 };
314 #endif
315 
316 static struct xenbus_watch shutdown_watch = {
317 	.node = "control/shutdown",
318 	.callback = shutdown_handler
319 };
320 
321 static struct notifier_block xen_reboot_nb = {
322 	.notifier_call = poweroff_nb,
323 };
324 
325 static int setup_shutdown_watcher(void)
326 {
327 	int err;
328 	int idx;
329 #define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
330 	char node[FEATURE_PATH_SIZE];
331 
332 	err = register_xenbus_watch(&shutdown_watch);
333 	if (err) {
334 		pr_err("Failed to set shutdown watcher\n");
335 		return err;
336 	}
337 
338 
339 #ifdef CONFIG_MAGIC_SYSRQ
340 	err = register_xenbus_watch(&sysrq_watch);
341 	if (err) {
342 		pr_err("Failed to set sysrq watcher\n");
343 		return err;
344 	}
345 #endif
346 
347 	for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
348 		if (!shutdown_handlers[idx].flag)
349 			continue;
350 		snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
351 			 shutdown_handlers[idx].command);
352 		err = xenbus_printf(XBT_NIL, "control", node, "%u", 1);
353 		if (err) {
354 			pr_err("%s: Error %d writing %s\n", __func__,
355 				err, node);
356 			return err;
357 		}
358 	}
359 
360 	return 0;
361 }
362 
363 static int shutdown_event(struct notifier_block *notifier,
364 			  unsigned long event,
365 			  void *data)
366 {
367 	setup_shutdown_watcher();
368 	return NOTIFY_DONE;
369 }
370 
371 int xen_setup_shutdown_event(void)
372 {
373 	static struct notifier_block xenstore_notifier = {
374 		.notifier_call = shutdown_event
375 	};
376 
377 	if (!xen_domain())
378 		return -ENODEV;
379 	register_xenstore_notifier(&xenstore_notifier);
380 	register_reboot_notifier(&xen_reboot_nb);
381 
382 	return 0;
383 }
384 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
385 
386 subsys_initcall(xen_setup_shutdown_event);
387