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