xref: /openbmc/linux/drivers/xen/manage.c (revision faa16bc4)
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 		xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
294 
295 	err = xenbus_transaction_end(xbt, 0);
296 	if (err == -EAGAIN)
297 		goto again;
298 
299 	if (sysrq_key != '\0')
300 		handle_sysrq(sysrq_key);
301 }
302 
303 static struct xenbus_watch sysrq_watch = {
304 	.node = "control/sysrq",
305 	.callback = sysrq_handler
306 };
307 #endif
308 
309 static struct xenbus_watch shutdown_watch = {
310 	.node = "control/shutdown",
311 	.callback = shutdown_handler
312 };
313 
314 static struct notifier_block xen_reboot_nb = {
315 	.notifier_call = poweroff_nb,
316 };
317 
318 static int setup_shutdown_watcher(void)
319 {
320 	int err;
321 	int idx;
322 #define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
323 	char node[FEATURE_PATH_SIZE];
324 
325 	err = register_xenbus_watch(&shutdown_watch);
326 	if (err) {
327 		pr_err("Failed to set shutdown watcher\n");
328 		return err;
329 	}
330 
331 
332 #ifdef CONFIG_MAGIC_SYSRQ
333 	err = register_xenbus_watch(&sysrq_watch);
334 	if (err) {
335 		pr_err("Failed to set sysrq watcher\n");
336 		return err;
337 	}
338 #endif
339 
340 	for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
341 		if (!shutdown_handlers[idx].flag)
342 			continue;
343 		snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
344 			 shutdown_handlers[idx].command);
345 		xenbus_printf(XBT_NIL, "control", node, "%u", 1);
346 	}
347 
348 	return 0;
349 }
350 
351 static int shutdown_event(struct notifier_block *notifier,
352 			  unsigned long event,
353 			  void *data)
354 {
355 	setup_shutdown_watcher();
356 	return NOTIFY_DONE;
357 }
358 
359 int xen_setup_shutdown_event(void)
360 {
361 	static struct notifier_block xenstore_notifier = {
362 		.notifier_call = shutdown_event
363 	};
364 
365 	if (!xen_domain())
366 		return -ENODEV;
367 	register_xenstore_notifier(&xenstore_notifier);
368 	register_reboot_notifier(&xen_reboot_nb);
369 
370 	return 0;
371 }
372 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
373 
374 subsys_initcall(xen_setup_shutdown_event);
375