1 /*
2  * Handle extern requests for shutdown, reboot and sysrq
3  */
4 #include <linux/kernel.h>
5 #include <linux/err.h>
6 #include <linux/slab.h>
7 #include <linux/reboot.h>
8 #include <linux/sysrq.h>
9 #include <linux/stop_machine.h>
10 #include <linux/freezer.h>
11 #include <linux/syscore_ops.h>
12 
13 #include <xen/xen.h>
14 #include <xen/xenbus.h>
15 #include <xen/grant_table.h>
16 #include <xen/events.h>
17 #include <xen/hvc-console.h>
18 #include <xen/xen-ops.h>
19 
20 #include <asm/xen/hypercall.h>
21 #include <asm/xen/page.h>
22 #include <asm/xen/hypervisor.h>
23 
24 enum shutdown_state {
25 	SHUTDOWN_INVALID = -1,
26 	SHUTDOWN_POWEROFF = 0,
27 	SHUTDOWN_SUSPEND = 2,
28 	/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
29 	   report a crash, not be instructed to crash!
30 	   HALT is the same as POWEROFF, as far as we're concerned.  The tools use
31 	   the distinction when we return the reason code to them.  */
32 	 SHUTDOWN_HALT = 4,
33 };
34 
35 /* Ignore multiple shutdown requests. */
36 static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
37 
38 struct suspend_info {
39 	int cancelled;
40 	unsigned long arg; /* extra hypercall argument */
41 	void (*pre)(void);
42 	void (*post)(int cancelled);
43 };
44 
xen_hvm_post_suspend(int cancelled)45 static void xen_hvm_post_suspend(int cancelled)
46 {
47 	xen_arch_hvm_post_suspend(cancelled);
48 	gnttab_resume();
49 }
50 
xen_pre_suspend(void)51 static void xen_pre_suspend(void)
52 {
53 	xen_mm_pin_all();
54 	gnttab_suspend();
55 	xen_arch_pre_suspend();
56 }
57 
xen_post_suspend(int cancelled)58 static void xen_post_suspend(int cancelled)
59 {
60 	xen_arch_post_suspend(cancelled);
61 	gnttab_resume();
62 	xen_mm_unpin_all();
63 }
64 
65 #ifdef CONFIG_HIBERNATE_CALLBACKS
xen_suspend(void * data)66 static int xen_suspend(void *data)
67 {
68 	struct suspend_info *si = data;
69 	int err;
70 
71 	BUG_ON(!irqs_disabled());
72 
73 	err = sysdev_suspend(PMSG_FREEZE);
74 	if (!err) {
75 		err = syscore_suspend();
76 		if (err)
77 			sysdev_resume();
78 	}
79 	if (err) {
80 		printk(KERN_ERR "xen_suspend: system core suspend failed: %d\n",
81 			err);
82 		return err;
83 	}
84 
85 	if (si->pre)
86 		si->pre();
87 
88 	/*
89 	 * This hypercall returns 1 if suspend was cancelled
90 	 * or the domain was merely checkpointed, and 0 if it
91 	 * is resuming in a new domain.
92 	 */
93 	si->cancelled = HYPERVISOR_suspend(si->arg);
94 
95 	if (si->post)
96 		si->post(si->cancelled);
97 
98 	if (!si->cancelled) {
99 		xen_irq_resume();
100 		xen_console_resume();
101 		xen_timer_resume();
102 	}
103 
104 	syscore_resume();
105 	sysdev_resume();
106 
107 	return 0;
108 }
109 
do_suspend(void)110 static void do_suspend(void)
111 {
112 	int err;
113 	struct suspend_info si;
114 
115 	shutting_down = SHUTDOWN_SUSPEND;
116 
117 #ifdef CONFIG_PREEMPT
118 	/* If the kernel is preemptible, we need to freeze all the processes
119 	   to prevent them from being in the middle of a pagetable update
120 	   during suspend. */
121 	err = freeze_processes();
122 	if (err) {
123 		printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
124 		goto out;
125 	}
126 #endif
127 
128 	err = dpm_suspend_start(PMSG_FREEZE);
129 	if (err) {
130 		printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err);
131 		goto out_thaw;
132 	}
133 
134 	printk(KERN_DEBUG "suspending xenstore...\n");
135 	xs_suspend();
136 
137 	err = dpm_suspend_noirq(PMSG_FREEZE);
138 	if (err) {
139 		printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
140 		goto out_resume;
141 	}
142 
143 	si.cancelled = 1;
144 
145 	if (xen_hvm_domain()) {
146 		si.arg = 0UL;
147 		si.pre = NULL;
148 		si.post = &xen_hvm_post_suspend;
149 	} else {
150 		si.arg = virt_to_mfn(xen_start_info);
151 		si.pre = &xen_pre_suspend;
152 		si.post = &xen_post_suspend;
153 	}
154 
155 	err = stop_machine(xen_suspend, &si, cpumask_of(0));
156 
157 	dpm_resume_noirq(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
158 
159 	if (err) {
160 		printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
161 		si.cancelled = 1;
162 	}
163 
164 out_resume:
165 	if (!si.cancelled) {
166 		xen_arch_resume();
167 		xs_resume();
168 	} else
169 		xs_suspend_cancel();
170 
171 	dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
172 
173 	/* Make sure timer events get retriggered on all CPUs */
174 	clock_was_set();
175 
176 out_thaw:
177 #ifdef CONFIG_PREEMPT
178 	thaw_processes();
179 out:
180 #endif
181 	shutting_down = SHUTDOWN_INVALID;
182 }
183 #endif	/* CONFIG_HIBERNATE_CALLBACKS */
184 
185 struct shutdown_handler {
186 	const char *command;
187 	void (*cb)(void);
188 };
189 
do_poweroff(void)190 static void do_poweroff(void)
191 {
192 	shutting_down = SHUTDOWN_POWEROFF;
193 	orderly_poweroff(false);
194 }
195 
do_reboot(void)196 static void do_reboot(void)
197 {
198 	shutting_down = SHUTDOWN_POWEROFF; /* ? */
199 	ctrl_alt_del();
200 }
201 
shutdown_handler(struct xenbus_watch * watch,const char ** vec,unsigned int len)202 static void shutdown_handler(struct xenbus_watch *watch,
203 			     const char **vec, unsigned int len)
204 {
205 	char *str;
206 	struct xenbus_transaction xbt;
207 	int err;
208 	static struct shutdown_handler handlers[] = {
209 		{ "poweroff",	do_poweroff },
210 		{ "halt",	do_poweroff },
211 		{ "reboot",	do_reboot   },
212 #ifdef CONFIG_HIBERNATE_CALLBACKS
213 		{ "suspend",	do_suspend  },
214 #endif
215 		{NULL, NULL},
216 	};
217 	static struct shutdown_handler *handler;
218 
219 	if (shutting_down != SHUTDOWN_INVALID)
220 		return;
221 
222  again:
223 	err = xenbus_transaction_start(&xbt);
224 	if (err)
225 		return;
226 
227 	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
228 	/* Ignore read errors and empty reads. */
229 	if (XENBUS_IS_ERR_READ(str)) {
230 		xenbus_transaction_end(xbt, 1);
231 		return;
232 	}
233 
234 	for (handler = &handlers[0]; handler->command; handler++) {
235 		if (strcmp(str, handler->command) == 0)
236 			break;
237 	}
238 
239 	/* Only acknowledge commands which we are prepared to handle. */
240 	if (handler->cb)
241 		xenbus_write(xbt, "control", "shutdown", "");
242 
243 	err = xenbus_transaction_end(xbt, 0);
244 	if (err == -EAGAIN) {
245 		kfree(str);
246 		goto again;
247 	}
248 
249 	if (handler->cb) {
250 		handler->cb();
251 	} else {
252 		printk(KERN_INFO "Ignoring shutdown request: %s\n", str);
253 		shutting_down = SHUTDOWN_INVALID;
254 	}
255 
256 	kfree(str);
257 }
258 
259 #ifdef CONFIG_MAGIC_SYSRQ
sysrq_handler(struct xenbus_watch * watch,const char ** vec,unsigned int len)260 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
261 			  unsigned int len)
262 {
263 	char sysrq_key = '\0';
264 	struct xenbus_transaction xbt;
265 	int err;
266 
267  again:
268 	err = xenbus_transaction_start(&xbt);
269 	if (err)
270 		return;
271 	if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
272 		printk(KERN_ERR "Unable to read sysrq code in "
273 		       "control/sysrq\n");
274 		xenbus_transaction_end(xbt, 1);
275 		return;
276 	}
277 
278 	if (sysrq_key != '\0')
279 		xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
280 
281 	err = xenbus_transaction_end(xbt, 0);
282 	if (err == -EAGAIN)
283 		goto again;
284 
285 	if (sysrq_key != '\0')
286 		handle_sysrq(sysrq_key);
287 }
288 
289 static struct xenbus_watch sysrq_watch = {
290 	.node = "control/sysrq",
291 	.callback = sysrq_handler
292 };
293 #endif
294 
295 static struct xenbus_watch shutdown_watch = {
296 	.node = "control/shutdown",
297 	.callback = shutdown_handler
298 };
299 
setup_shutdown_watcher(void)300 static int setup_shutdown_watcher(void)
301 {
302 	int err;
303 
304 	err = register_xenbus_watch(&shutdown_watch);
305 	if (err) {
306 		printk(KERN_ERR "Failed to set shutdown watcher\n");
307 		return err;
308 	}
309 
310 #ifdef CONFIG_MAGIC_SYSRQ
311 	err = register_xenbus_watch(&sysrq_watch);
312 	if (err) {
313 		printk(KERN_ERR "Failed to set sysrq watcher\n");
314 		return err;
315 	}
316 #endif
317 
318 	return 0;
319 }
320 
shutdown_event(struct notifier_block * notifier,unsigned long event,void * data)321 static int shutdown_event(struct notifier_block *notifier,
322 			  unsigned long event,
323 			  void *data)
324 {
325 	setup_shutdown_watcher();
326 	return NOTIFY_DONE;
327 }
328 
xen_setup_shutdown_event(void)329 int xen_setup_shutdown_event(void)
330 {
331 	static struct notifier_block xenstore_notifier = {
332 		.notifier_call = shutdown_event
333 	};
334 
335 	if (!xen_domain())
336 		return -ENODEV;
337 	register_xenstore_notifier(&xenstore_notifier);
338 
339 	return 0;
340 }
341 EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
342 
343 subsys_initcall(xen_setup_shutdown_event);
344