xref: /linux/drivers/xen/manage.c (revision 0c93ea4064a209cdc36de8a9a3003d43d08f46f7)
1 /*
2  * Handle extern requests for shutdown, reboot and sysrq
3  */
4 #include <linux/kernel.h>
5 #include <linux/err.h>
6 #include <linux/reboot.h>
7 #include <linux/sysrq.h>
8 #include <linux/stop_machine.h>
9 #include <linux/freezer.h>
10 
11 #include <xen/xenbus.h>
12 #include <xen/grant_table.h>
13 #include <xen/events.h>
14 #include <xen/hvc-console.h>
15 #include <xen/xen-ops.h>
16 
17 #include <asm/xen/hypercall.h>
18 #include <asm/xen/page.h>
19 
20 enum shutdown_state {
21 	SHUTDOWN_INVALID = -1,
22 	SHUTDOWN_POWEROFF = 0,
23 	SHUTDOWN_SUSPEND = 2,
24 	/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
25 	   report a crash, not be instructed to crash!
26 	   HALT is the same as POWEROFF, as far as we're concerned.  The tools use
27 	   the distinction when we return the reason code to them.  */
28 	 SHUTDOWN_HALT = 4,
29 };
30 
31 /* Ignore multiple shutdown requests. */
32 static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
33 
34 #ifdef CONFIG_PM_SLEEP
35 static int xen_suspend(void *data)
36 {
37 	int *cancelled = data;
38 	int err;
39 
40 	BUG_ON(!irqs_disabled());
41 
42 	err = device_power_down(PMSG_SUSPEND);
43 	if (err) {
44 		printk(KERN_ERR "xen_suspend: device_power_down failed: %d\n",
45 		       err);
46 		return err;
47 	}
48 	err = sysdev_suspend(PMSG_SUSPEND);
49 	if (err) {
50 		printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
51 			err);
52 		device_power_up(PMSG_RESUME);
53 		return err;
54 	}
55 
56 	xen_mm_pin_all();
57 	gnttab_suspend();
58 	xen_pre_suspend();
59 
60 	/*
61 	 * This hypercall returns 1 if suspend was cancelled
62 	 * or the domain was merely checkpointed, and 0 if it
63 	 * is resuming in a new domain.
64 	 */
65 	*cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
66 
67 	xen_post_suspend(*cancelled);
68 	gnttab_resume();
69 	xen_mm_unpin_all();
70 
71 	sysdev_resume();
72 	device_power_up(PMSG_RESUME);
73 
74 	if (!*cancelled) {
75 		xen_irq_resume();
76 		xen_console_resume();
77 		xen_timer_resume();
78 	}
79 
80 	return 0;
81 }
82 
83 static void do_suspend(void)
84 {
85 	int err;
86 	int cancelled = 1;
87 
88 	shutting_down = SHUTDOWN_SUSPEND;
89 
90 #ifdef CONFIG_PREEMPT
91 	/* If the kernel is preemptible, we need to freeze all the processes
92 	   to prevent them from being in the middle of a pagetable update
93 	   during suspend. */
94 	err = freeze_processes();
95 	if (err) {
96 		printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
97 		return;
98 	}
99 #endif
100 
101 	err = device_suspend(PMSG_SUSPEND);
102 	if (err) {
103 		printk(KERN_ERR "xen suspend: device_suspend %d\n", err);
104 		goto out;
105 	}
106 
107 	printk("suspending xenbus...\n");
108 	/* XXX use normal device tree? */
109 	xenbus_suspend();
110 
111 	err = stop_machine(xen_suspend, &cancelled, &cpumask_of_cpu(0));
112 	if (err) {
113 		printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
114 		goto out;
115 	}
116 
117 	if (!cancelled) {
118 		xen_arch_resume();
119 		xenbus_resume();
120 	} else
121 		xenbus_suspend_cancel();
122 
123 	device_resume(PMSG_RESUME);
124 
125 	/* Make sure timer events get retriggered on all CPUs */
126 	clock_was_set();
127 out:
128 #ifdef CONFIG_PREEMPT
129 	thaw_processes();
130 #endif
131 	shutting_down = SHUTDOWN_INVALID;
132 }
133 #endif	/* CONFIG_PM_SLEEP */
134 
135 static void shutdown_handler(struct xenbus_watch *watch,
136 			     const char **vec, unsigned int len)
137 {
138 	char *str;
139 	struct xenbus_transaction xbt;
140 	int err;
141 
142 	if (shutting_down != SHUTDOWN_INVALID)
143 		return;
144 
145  again:
146 	err = xenbus_transaction_start(&xbt);
147 	if (err)
148 		return;
149 
150 	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
151 	/* Ignore read errors and empty reads. */
152 	if (XENBUS_IS_ERR_READ(str)) {
153 		xenbus_transaction_end(xbt, 1);
154 		return;
155 	}
156 
157 	xenbus_write(xbt, "control", "shutdown", "");
158 
159 	err = xenbus_transaction_end(xbt, 0);
160 	if (err == -EAGAIN) {
161 		kfree(str);
162 		goto again;
163 	}
164 
165 	if (strcmp(str, "poweroff") == 0 ||
166 	    strcmp(str, "halt") == 0) {
167 		shutting_down = SHUTDOWN_POWEROFF;
168 		orderly_poweroff(false);
169 	} else if (strcmp(str, "reboot") == 0) {
170 		shutting_down = SHUTDOWN_POWEROFF; /* ? */
171 		ctrl_alt_del();
172 #ifdef CONFIG_PM_SLEEP
173 	} else if (strcmp(str, "suspend") == 0) {
174 		do_suspend();
175 #endif
176 	} else {
177 		printk(KERN_INFO "Ignoring shutdown request: %s\n", str);
178 		shutting_down = SHUTDOWN_INVALID;
179 	}
180 
181 	kfree(str);
182 }
183 
184 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
185 			  unsigned int len)
186 {
187 	char sysrq_key = '\0';
188 	struct xenbus_transaction xbt;
189 	int err;
190 
191  again:
192 	err = xenbus_transaction_start(&xbt);
193 	if (err)
194 		return;
195 	if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
196 		printk(KERN_ERR "Unable to read sysrq code in "
197 		       "control/sysrq\n");
198 		xenbus_transaction_end(xbt, 1);
199 		return;
200 	}
201 
202 	if (sysrq_key != '\0')
203 		xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
204 
205 	err = xenbus_transaction_end(xbt, 0);
206 	if (err == -EAGAIN)
207 		goto again;
208 
209 	if (sysrq_key != '\0')
210 		handle_sysrq(sysrq_key, NULL);
211 }
212 
213 static struct xenbus_watch shutdown_watch = {
214 	.node = "control/shutdown",
215 	.callback = shutdown_handler
216 };
217 
218 static struct xenbus_watch sysrq_watch = {
219 	.node = "control/sysrq",
220 	.callback = sysrq_handler
221 };
222 
223 static int setup_shutdown_watcher(void)
224 {
225 	int err;
226 
227 	err = register_xenbus_watch(&shutdown_watch);
228 	if (err) {
229 		printk(KERN_ERR "Failed to set shutdown watcher\n");
230 		return err;
231 	}
232 
233 	err = register_xenbus_watch(&sysrq_watch);
234 	if (err) {
235 		printk(KERN_ERR "Failed to set sysrq watcher\n");
236 		return err;
237 	}
238 
239 	return 0;
240 }
241 
242 static int shutdown_event(struct notifier_block *notifier,
243 			  unsigned long event,
244 			  void *data)
245 {
246 	setup_shutdown_watcher();
247 	return NOTIFY_DONE;
248 }
249 
250 static int __init setup_shutdown_event(void)
251 {
252 	static struct notifier_block xenstore_notifier = {
253 		.notifier_call = shutdown_event
254 	};
255 	register_xenstore_notifier(&xenstore_notifier);
256 
257 	return 0;
258 }
259 
260 subsys_initcall(setup_shutdown_event);
261