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