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