xref: /openbmc/linux/drivers/xen/manage.c (revision 206204a1)
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/xen-ops.h>
23 
24 #include <asm/xen/hypercall.h>
25 #include <asm/xen/page.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_arch_pre_suspend();
76 
77 	/*
78 	 * This hypercall returns 1 if suspend was cancelled
79 	 * or the domain was merely checkpointed, and 0 if it
80 	 * is resuming in a new domain.
81 	 */
82 	si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
83                                            ? virt_to_mfn(xen_start_info)
84                                            : 0);
85 
86 	xen_arch_post_suspend(si->cancelled);
87 	gnttab_resume();
88 
89 	if (!si->cancelled) {
90 		xen_irq_resume();
91 		xen_console_resume();
92 		xen_timer_resume();
93 	}
94 
95 	syscore_resume();
96 
97 	return 0;
98 }
99 
100 static void do_suspend(void)
101 {
102 	int err;
103 	struct suspend_info si;
104 
105 	shutting_down = SHUTDOWN_SUSPEND;
106 
107 #ifdef CONFIG_PREEMPT
108 	/* If the kernel is preemptible, we need to freeze all the processes
109 	   to prevent them from being in the middle of a pagetable update
110 	   during suspend. */
111 	err = freeze_processes();
112 	if (err) {
113 		pr_err("%s: freeze failed %d\n", __func__, err);
114 		goto out;
115 	}
116 #endif
117 
118 	err = dpm_suspend_start(PMSG_FREEZE);
119 	if (err) {
120 		pr_err("%s: dpm_suspend_start %d\n", __func__, err);
121 		goto out_thaw;
122 	}
123 
124 	printk(KERN_DEBUG "suspending xenstore...\n");
125 	xs_suspend();
126 
127 	err = dpm_suspend_end(PMSG_FREEZE);
128 	if (err) {
129 		pr_err("dpm_suspend_end failed: %d\n", err);
130 		si.cancelled = 0;
131 		goto out_resume;
132 	}
133 
134 	si.cancelled = 1;
135 
136 	err = stop_machine(xen_suspend, &si, cpumask_of(0));
137 
138 	raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
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 		xen_arch_resume();
150 		xs_resume();
151 	} else
152 		xs_suspend_cancel();
153 
154 	dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
155 
156 out_thaw:
157 #ifdef CONFIG_PREEMPT
158 	thaw_processes();
159 out:
160 #endif
161 	shutting_down = SHUTDOWN_INVALID;
162 }
163 #endif	/* CONFIG_HIBERNATE_CALLBACKS */
164 
165 struct shutdown_handler {
166 	const char *command;
167 	void (*cb)(void);
168 };
169 
170 static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
171 {
172 	switch (code) {
173 	case SYS_DOWN:
174 	case SYS_HALT:
175 	case SYS_POWER_OFF:
176 		shutting_down = SHUTDOWN_POWEROFF;
177 	default:
178 		break;
179 	}
180 	return NOTIFY_DONE;
181 }
182 static void do_poweroff(void)
183 {
184 	switch (system_state) {
185 	case SYSTEM_BOOTING:
186 		orderly_poweroff(true);
187 		break;
188 	case SYSTEM_RUNNING:
189 		orderly_poweroff(false);
190 		break;
191 	default:
192 		/* Don't do it when we are halting/rebooting. */
193 		pr_info("Ignoring Xen toolstack shutdown.\n");
194 		break;
195 	}
196 }
197 
198 static void do_reboot(void)
199 {
200 	shutting_down = SHUTDOWN_POWEROFF; /* ? */
201 	ctrl_alt_del();
202 }
203 
204 static void shutdown_handler(struct xenbus_watch *watch,
205 			     const char **vec, unsigned int len)
206 {
207 	char *str;
208 	struct xenbus_transaction xbt;
209 	int err;
210 	static struct shutdown_handler handlers[] = {
211 		{ "poweroff",	do_poweroff },
212 		{ "halt",	do_poweroff },
213 		{ "reboot",	do_reboot   },
214 #ifdef CONFIG_HIBERNATE_CALLBACKS
215 		{ "suspend",	do_suspend  },
216 #endif
217 		{NULL, NULL},
218 	};
219 	static struct shutdown_handler *handler;
220 
221 	if (shutting_down != SHUTDOWN_INVALID)
222 		return;
223 
224  again:
225 	err = xenbus_transaction_start(&xbt);
226 	if (err)
227 		return;
228 
229 	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
230 	/* Ignore read errors and empty reads. */
231 	if (XENBUS_IS_ERR_READ(str)) {
232 		xenbus_transaction_end(xbt, 1);
233 		return;
234 	}
235 
236 	for (handler = &handlers[0]; handler->command; handler++) {
237 		if (strcmp(str, handler->command) == 0)
238 			break;
239 	}
240 
241 	/* Only acknowledge commands which we are prepared to handle. */
242 	if (handler->cb)
243 		xenbus_write(xbt, "control", "shutdown", "");
244 
245 	err = xenbus_transaction_end(xbt, 0);
246 	if (err == -EAGAIN) {
247 		kfree(str);
248 		goto again;
249 	}
250 
251 	if (handler->cb) {
252 		handler->cb();
253 	} else {
254 		pr_info("Ignoring shutdown request: %s\n", str);
255 		shutting_down = SHUTDOWN_INVALID;
256 	}
257 
258 	kfree(str);
259 }
260 
261 #ifdef CONFIG_MAGIC_SYSRQ
262 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
263 			  unsigned int len)
264 {
265 	char sysrq_key = '\0';
266 	struct xenbus_transaction xbt;
267 	int err;
268 
269  again:
270 	err = xenbus_transaction_start(&xbt);
271 	if (err)
272 		return;
273 	if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
274 		pr_err("Unable to read sysrq code in control/sysrq\n");
275 		xenbus_transaction_end(xbt, 1);
276 		return;
277 	}
278 
279 	if (sysrq_key != '\0')
280 		xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
281 
282 	err = xenbus_transaction_end(xbt, 0);
283 	if (err == -EAGAIN)
284 		goto again;
285 
286 	if (sysrq_key != '\0')
287 		handle_sysrq(sysrq_key);
288 }
289 
290 static struct xenbus_watch sysrq_watch = {
291 	.node = "control/sysrq",
292 	.callback = sysrq_handler
293 };
294 #endif
295 
296 static struct xenbus_watch shutdown_watch = {
297 	.node = "control/shutdown",
298 	.callback = shutdown_handler
299 };
300 
301 static struct notifier_block xen_reboot_nb = {
302 	.notifier_call = poweroff_nb,
303 };
304 
305 static int setup_shutdown_watcher(void)
306 {
307 	int err;
308 
309 	err = register_xenbus_watch(&shutdown_watch);
310 	if (err) {
311 		pr_err("Failed to set shutdown watcher\n");
312 		return err;
313 	}
314 
315 
316 #ifdef CONFIG_MAGIC_SYSRQ
317 	err = register_xenbus_watch(&sysrq_watch);
318 	if (err) {
319 		pr_err("Failed to set sysrq watcher\n");
320 		return err;
321 	}
322 #endif
323 
324 	return 0;
325 }
326 
327 static int shutdown_event(struct notifier_block *notifier,
328 			  unsigned long event,
329 			  void *data)
330 {
331 	setup_shutdown_watcher();
332 	return NOTIFY_DONE;
333 }
334 
335 int xen_setup_shutdown_event(void)
336 {
337 	static struct notifier_block xenstore_notifier = {
338 		.notifier_call = shutdown_event
339 	};
340 
341 	if (!xen_domain())
342 		return -ENODEV;
343 	register_xenstore_notifier(&xenstore_notifier);
344 	register_reboot_notifier(&xen_reboot_nb);
345 
346 	return 0;
347 }
348 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
349 
350 subsys_initcall(xen_setup_shutdown_event);
351