xref: /openbmc/linux/drivers/xen/manage.c (revision 3a0d89d3)
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 	unsigned long arg; /* extra hypercall argument */
45 	void (*pre)(void);
46 	void (*post)(int cancelled);
47 };
48 
49 static RAW_NOTIFIER_HEAD(xen_resume_notifier);
50 
51 void xen_resume_notifier_register(struct notifier_block *nb)
52 {
53 	raw_notifier_chain_register(&xen_resume_notifier, nb);
54 }
55 EXPORT_SYMBOL_GPL(xen_resume_notifier_register);
56 
57 void xen_resume_notifier_unregister(struct notifier_block *nb)
58 {
59 	raw_notifier_chain_unregister(&xen_resume_notifier, nb);
60 }
61 EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
62 
63 #ifdef CONFIG_HIBERNATE_CALLBACKS
64 static void xen_hvm_post_suspend(int cancelled)
65 {
66 	xen_arch_hvm_post_suspend(cancelled);
67 	gnttab_resume();
68 }
69 
70 static void xen_pre_suspend(void)
71 {
72 	xen_mm_pin_all();
73 	gnttab_suspend();
74 	xen_arch_pre_suspend();
75 }
76 
77 static void xen_post_suspend(int cancelled)
78 {
79 	xen_arch_post_suspend(cancelled);
80 	gnttab_resume();
81 	xen_mm_unpin_all();
82 }
83 
84 static int xen_suspend(void *data)
85 {
86 	struct suspend_info *si = data;
87 	int err;
88 
89 	BUG_ON(!irqs_disabled());
90 
91 	err = syscore_suspend();
92 	if (err) {
93 		pr_err("%s: system core suspend failed: %d\n", __func__, err);
94 		return err;
95 	}
96 
97 	if (si->pre)
98 		si->pre();
99 
100 	/*
101 	 * This hypercall returns 1 if suspend was cancelled
102 	 * or the domain was merely checkpointed, and 0 if it
103 	 * is resuming in a new domain.
104 	 */
105 	si->cancelled = HYPERVISOR_suspend(si->arg);
106 
107 	if (si->post)
108 		si->post(si->cancelled);
109 
110 	if (!si->cancelled) {
111 		xen_irq_resume();
112 		xen_console_resume();
113 		xen_timer_resume();
114 	}
115 
116 	syscore_resume();
117 
118 	return 0;
119 }
120 
121 static void do_suspend(void)
122 {
123 	int err;
124 	struct suspend_info si;
125 
126 	shutting_down = SHUTDOWN_SUSPEND;
127 
128 #ifdef CONFIG_PREEMPT
129 	/* If the kernel is preemptible, we need to freeze all the processes
130 	   to prevent them from being in the middle of a pagetable update
131 	   during suspend. */
132 	err = freeze_processes();
133 	if (err) {
134 		pr_err("%s: freeze failed %d\n", __func__, err);
135 		goto out;
136 	}
137 #endif
138 
139 	err = dpm_suspend_start(PMSG_FREEZE);
140 	if (err) {
141 		pr_err("%s: dpm_suspend_start %d\n", __func__, err);
142 		goto out_thaw;
143 	}
144 
145 	printk(KERN_DEBUG "suspending xenstore...\n");
146 	xs_suspend();
147 
148 	err = dpm_suspend_end(PMSG_FREEZE);
149 	if (err) {
150 		pr_err("dpm_suspend_end failed: %d\n", err);
151 		si.cancelled = 0;
152 		goto out_resume;
153 	}
154 
155 	si.cancelled = 1;
156 
157 	if (xen_hvm_domain()) {
158 		si.arg = 0UL;
159 		si.pre = NULL;
160 		si.post = &xen_hvm_post_suspend;
161 	} else {
162 		si.arg = virt_to_mfn(xen_start_info);
163 		si.pre = &xen_pre_suspend;
164 		si.post = &xen_post_suspend;
165 	}
166 
167 	err = stop_machine(xen_suspend, &si, cpumask_of(0));
168 
169 	raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
170 
171 	dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
172 
173 	if (err) {
174 		pr_err("failed to start xen_suspend: %d\n", err);
175 		si.cancelled = 1;
176 	}
177 
178 out_resume:
179 	if (!si.cancelled) {
180 		xen_arch_resume();
181 		xs_resume();
182 	} else
183 		xs_suspend_cancel();
184 
185 	dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
186 
187 out_thaw:
188 #ifdef CONFIG_PREEMPT
189 	thaw_processes();
190 out:
191 #endif
192 	shutting_down = SHUTDOWN_INVALID;
193 }
194 #endif	/* CONFIG_HIBERNATE_CALLBACKS */
195 
196 struct shutdown_handler {
197 	const char *command;
198 	void (*cb)(void);
199 };
200 
201 static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
202 {
203 	switch (code) {
204 	case SYS_DOWN:
205 	case SYS_HALT:
206 	case SYS_POWER_OFF:
207 		shutting_down = SHUTDOWN_POWEROFF;
208 	default:
209 		break;
210 	}
211 	return NOTIFY_DONE;
212 }
213 static void do_poweroff(void)
214 {
215 	switch (system_state) {
216 	case SYSTEM_BOOTING:
217 		orderly_poweroff(true);
218 		break;
219 	case SYSTEM_RUNNING:
220 		orderly_poweroff(false);
221 		break;
222 	default:
223 		/* Don't do it when we are halting/rebooting. */
224 		pr_info("Ignoring Xen toolstack shutdown.\n");
225 		break;
226 	}
227 }
228 
229 static void do_reboot(void)
230 {
231 	shutting_down = SHUTDOWN_POWEROFF; /* ? */
232 	ctrl_alt_del();
233 }
234 
235 static void shutdown_handler(struct xenbus_watch *watch,
236 			     const char **vec, unsigned int len)
237 {
238 	char *str;
239 	struct xenbus_transaction xbt;
240 	int err;
241 	static struct shutdown_handler handlers[] = {
242 		{ "poweroff",	do_poweroff },
243 		{ "halt",	do_poweroff },
244 		{ "reboot",	do_reboot   },
245 #ifdef CONFIG_HIBERNATE_CALLBACKS
246 		{ "suspend",	do_suspend  },
247 #endif
248 		{NULL, NULL},
249 	};
250 	static struct shutdown_handler *handler;
251 
252 	if (shutting_down != SHUTDOWN_INVALID)
253 		return;
254 
255  again:
256 	err = xenbus_transaction_start(&xbt);
257 	if (err)
258 		return;
259 
260 	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
261 	/* Ignore read errors and empty reads. */
262 	if (XENBUS_IS_ERR_READ(str)) {
263 		xenbus_transaction_end(xbt, 1);
264 		return;
265 	}
266 
267 	for (handler = &handlers[0]; handler->command; handler++) {
268 		if (strcmp(str, handler->command) == 0)
269 			break;
270 	}
271 
272 	/* Only acknowledge commands which we are prepared to handle. */
273 	if (handler->cb)
274 		xenbus_write(xbt, "control", "shutdown", "");
275 
276 	err = xenbus_transaction_end(xbt, 0);
277 	if (err == -EAGAIN) {
278 		kfree(str);
279 		goto again;
280 	}
281 
282 	if (handler->cb) {
283 		handler->cb();
284 	} else {
285 		pr_info("Ignoring shutdown request: %s\n", str);
286 		shutting_down = SHUTDOWN_INVALID;
287 	}
288 
289 	kfree(str);
290 }
291 
292 #ifdef CONFIG_MAGIC_SYSRQ
293 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
294 			  unsigned int len)
295 {
296 	char sysrq_key = '\0';
297 	struct xenbus_transaction xbt;
298 	int err;
299 
300  again:
301 	err = xenbus_transaction_start(&xbt);
302 	if (err)
303 		return;
304 	if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
305 		pr_err("Unable to read sysrq code in control/sysrq\n");
306 		xenbus_transaction_end(xbt, 1);
307 		return;
308 	}
309 
310 	if (sysrq_key != '\0')
311 		xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
312 
313 	err = xenbus_transaction_end(xbt, 0);
314 	if (err == -EAGAIN)
315 		goto again;
316 
317 	if (sysrq_key != '\0')
318 		handle_sysrq(sysrq_key);
319 }
320 
321 static struct xenbus_watch sysrq_watch = {
322 	.node = "control/sysrq",
323 	.callback = sysrq_handler
324 };
325 #endif
326 
327 static struct xenbus_watch shutdown_watch = {
328 	.node = "control/shutdown",
329 	.callback = shutdown_handler
330 };
331 
332 static struct notifier_block xen_reboot_nb = {
333 	.notifier_call = poweroff_nb,
334 };
335 
336 static int setup_shutdown_watcher(void)
337 {
338 	int err;
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 	return 0;
356 }
357 
358 static int shutdown_event(struct notifier_block *notifier,
359 			  unsigned long event,
360 			  void *data)
361 {
362 	setup_shutdown_watcher();
363 	return NOTIFY_DONE;
364 }
365 
366 int xen_setup_shutdown_event(void)
367 {
368 	static struct notifier_block xenstore_notifier = {
369 		.notifier_call = shutdown_event
370 	};
371 
372 	if (!xen_domain())
373 		return -ENODEV;
374 	register_xenstore_notifier(&xenstore_notifier);
375 	register_reboot_notifier(&xen_reboot_nb);
376 
377 	return 0;
378 }
379 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
380 
381 subsys_initcall(xen_setup_shutdown_event);
382