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