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 
xen_resume_notifier_register(struct notifier_block * nb)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 
xen_resume_notifier_unregister(struct notifier_block * nb)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
xen_suspend(void * data)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 
do_suspend(void)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 
poweroff_nb(struct notifier_block * cb,unsigned long code,void * unused)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 }
do_poweroff(void)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 
do_reboot(void)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 
shutdown_handler(struct xenbus_watch * watch,const char * path,const char * token)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
sysrq_handler(struct xenbus_watch * watch,const char * path,const char * token)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. ERANGE is observed when we get
284 		 * an empty value (''), this happens when we acknowledge the
285 		 * request by writing '\0' below.
286 		 */
287 		if (err != -ENOENT && err != -ERANGE)
288 			pr_err("Error %d reading sysrq code in control/sysrq\n",
289 			       err);
290 		xenbus_transaction_end(xbt, 1);
291 		return;
292 	}
293 
294 	if (sysrq_key != '\0') {
295 		err = xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
296 		if (err) {
297 			pr_err("%s: Error %d writing sysrq in control/sysrq\n",
298 			       __func__, err);
299 			xenbus_transaction_end(xbt, 1);
300 			return;
301 		}
302 	}
303 
304 	err = xenbus_transaction_end(xbt, 0);
305 	if (err == -EAGAIN)
306 		goto again;
307 
308 	if (sysrq_key != '\0')
309 		handle_sysrq(sysrq_key);
310 }
311 
312 static struct xenbus_watch sysrq_watch = {
313 	.node = "control/sysrq",
314 	.callback = sysrq_handler
315 };
316 #endif
317 
318 static struct xenbus_watch shutdown_watch = {
319 	.node = "control/shutdown",
320 	.callback = shutdown_handler
321 };
322 
323 static struct notifier_block xen_reboot_nb = {
324 	.notifier_call = poweroff_nb,
325 };
326 
setup_shutdown_watcher(void)327 static int setup_shutdown_watcher(void)
328 {
329 	int err;
330 	int idx;
331 #define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
332 	char node[FEATURE_PATH_SIZE];
333 
334 	err = register_xenbus_watch(&shutdown_watch);
335 	if (err) {
336 		pr_err("Failed to set shutdown watcher\n");
337 		return err;
338 	}
339 
340 
341 #ifdef CONFIG_MAGIC_SYSRQ
342 	err = register_xenbus_watch(&sysrq_watch);
343 	if (err) {
344 		pr_err("Failed to set sysrq watcher\n");
345 		return err;
346 	}
347 #endif
348 
349 	for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
350 		if (!shutdown_handlers[idx].flag)
351 			continue;
352 		snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
353 			 shutdown_handlers[idx].command);
354 		err = xenbus_printf(XBT_NIL, "control", node, "%u", 1);
355 		if (err) {
356 			pr_err("%s: Error %d writing %s\n", __func__,
357 				err, node);
358 			return err;
359 		}
360 	}
361 
362 	return 0;
363 }
364 
shutdown_event(struct notifier_block * notifier,unsigned long event,void * data)365 static int shutdown_event(struct notifier_block *notifier,
366 			  unsigned long event,
367 			  void *data)
368 {
369 	setup_shutdown_watcher();
370 	return NOTIFY_DONE;
371 }
372 
xen_setup_shutdown_event(void)373 int xen_setup_shutdown_event(void)
374 {
375 	static struct notifier_block xenstore_notifier = {
376 		.notifier_call = shutdown_event
377 	};
378 
379 	if (!xen_domain())
380 		return -ENODEV;
381 	register_xenstore_notifier(&xenstore_notifier);
382 	register_reboot_notifier(&xen_reboot_nb);
383 
384 	return 0;
385 }
386 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
387 
388 subsys_initcall(xen_setup_shutdown_event);
389