xref: /openbmc/linux/drivers/xen/manage.c (revision 6c870213d6f3a25981c10728f46294a3bed1703f)
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 void do_poweroff(void)
202 {
203 	shutting_down = SHUTDOWN_POWEROFF;
204 	orderly_poweroff(false);
205 }
206 
207 static void do_reboot(void)
208 {
209 	shutting_down = SHUTDOWN_POWEROFF; /* ? */
210 	ctrl_alt_del();
211 }
212 
213 static void shutdown_handler(struct xenbus_watch *watch,
214 			     const char **vec, unsigned int len)
215 {
216 	char *str;
217 	struct xenbus_transaction xbt;
218 	int err;
219 	static struct shutdown_handler handlers[] = {
220 		{ "poweroff",	do_poweroff },
221 		{ "halt",	do_poweroff },
222 		{ "reboot",	do_reboot   },
223 #ifdef CONFIG_HIBERNATE_CALLBACKS
224 		{ "suspend",	do_suspend  },
225 #endif
226 		{NULL, NULL},
227 	};
228 	static struct shutdown_handler *handler;
229 
230 	if (shutting_down != SHUTDOWN_INVALID)
231 		return;
232 
233  again:
234 	err = xenbus_transaction_start(&xbt);
235 	if (err)
236 		return;
237 
238 	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
239 	/* Ignore read errors and empty reads. */
240 	if (XENBUS_IS_ERR_READ(str)) {
241 		xenbus_transaction_end(xbt, 1);
242 		return;
243 	}
244 
245 	for (handler = &handlers[0]; handler->command; handler++) {
246 		if (strcmp(str, handler->command) == 0)
247 			break;
248 	}
249 
250 	/* Only acknowledge commands which we are prepared to handle. */
251 	if (handler->cb)
252 		xenbus_write(xbt, "control", "shutdown", "");
253 
254 	err = xenbus_transaction_end(xbt, 0);
255 	if (err == -EAGAIN) {
256 		kfree(str);
257 		goto again;
258 	}
259 
260 	if (handler->cb) {
261 		handler->cb();
262 	} else {
263 		pr_info("Ignoring shutdown request: %s\n", str);
264 		shutting_down = SHUTDOWN_INVALID;
265 	}
266 
267 	kfree(str);
268 }
269 
270 #ifdef CONFIG_MAGIC_SYSRQ
271 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
272 			  unsigned int len)
273 {
274 	char sysrq_key = '\0';
275 	struct xenbus_transaction xbt;
276 	int err;
277 
278  again:
279 	err = xenbus_transaction_start(&xbt);
280 	if (err)
281 		return;
282 	if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
283 		pr_err("Unable to read sysrq code in control/sysrq\n");
284 		xenbus_transaction_end(xbt, 1);
285 		return;
286 	}
287 
288 	if (sysrq_key != '\0')
289 		xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
290 
291 	err = xenbus_transaction_end(xbt, 0);
292 	if (err == -EAGAIN)
293 		goto again;
294 
295 	if (sysrq_key != '\0')
296 		handle_sysrq(sysrq_key);
297 }
298 
299 static struct xenbus_watch sysrq_watch = {
300 	.node = "control/sysrq",
301 	.callback = sysrq_handler
302 };
303 #endif
304 
305 static struct xenbus_watch shutdown_watch = {
306 	.node = "control/shutdown",
307 	.callback = shutdown_handler
308 };
309 
310 static int setup_shutdown_watcher(void)
311 {
312 	int err;
313 
314 	err = register_xenbus_watch(&shutdown_watch);
315 	if (err) {
316 		pr_err("Failed to set shutdown watcher\n");
317 		return err;
318 	}
319 
320 #ifdef CONFIG_MAGIC_SYSRQ
321 	err = register_xenbus_watch(&sysrq_watch);
322 	if (err) {
323 		pr_err("Failed to set sysrq watcher\n");
324 		return err;
325 	}
326 #endif
327 
328 	return 0;
329 }
330 
331 static int shutdown_event(struct notifier_block *notifier,
332 			  unsigned long event,
333 			  void *data)
334 {
335 	setup_shutdown_watcher();
336 	return NOTIFY_DONE;
337 }
338 
339 int xen_setup_shutdown_event(void)
340 {
341 	static struct notifier_block xenstore_notifier = {
342 		.notifier_call = shutdown_event
343 	};
344 
345 	if (!xen_domain())
346 		return -ENODEV;
347 	register_xenstore_notifier(&xenstore_notifier);
348 
349 	return 0;
350 }
351 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
352 
353 subsys_initcall(xen_setup_shutdown_event);
354