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