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