1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2010 Justin T. Gibbs, Spectra Logic Corporation 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * substantially similar to the "NO WARRANTY" disclaimer below 15 * ("Disclaimer") and any redistribution must be conditioned upon 16 * including a substantially similar Disclaimer requirement for further 17 * binary redistribution. 18 * 19 * NO WARRANTY 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGES. 31 */ 32 33 /*- 34 * HVM suspend/resume support: 35 * 36 * Copyright (c) 2008 Citrix Systems, Inc. 37 * All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 #include <sys/cdefs.h> 61 /** 62 * \file control.c 63 * 64 * \brief Device driver to repond to control domain events that impact 65 * this VM. 66 */ 67 68 #include <sys/param.h> 69 #include <sys/systm.h> 70 #include <sys/kernel.h> 71 #include <sys/malloc.h> 72 73 #include <sys/bio.h> 74 #include <sys/bus.h> 75 #include <sys/conf.h> 76 #include <sys/disk.h> 77 #include <sys/fcntl.h> 78 #include <sys/filedesc.h> 79 #include <sys/kdb.h> 80 #include <sys/module.h> 81 #include <sys/mount.h> 82 #include <sys/namei.h> 83 #include <sys/proc.h> 84 #include <sys/reboot.h> 85 #include <sys/rman.h> 86 #include <sys/sched.h> 87 #include <sys/taskqueue.h> 88 #include <sys/types.h> 89 #include <sys/vnode.h> 90 #include <sys/sched.h> 91 #include <sys/smp.h> 92 #include <sys/eventhandler.h> 93 #include <sys/timetc.h> 94 95 #include <geom/geom.h> 96 97 #include <machine/_inttypes.h> 98 #if defined(__amd64__) || defined(__i386__) 99 #include <machine/intr_machdep.h> 100 101 #include <x86/apicvar.h> 102 #endif 103 104 #include <vm/vm.h> 105 #include <vm/vm_extern.h> 106 #include <vm/vm_kern.h> 107 108 #include <xen/xen-os.h> 109 #include <xen/blkif.h> 110 #include <xen/evtchn.h> 111 #include <xen/gnttab.h> 112 #include <xen/xen_intr.h> 113 114 #include <xen/hvm.h> 115 116 #include <contrib/xen/event_channel.h> 117 #include <contrib/xen/grant_table.h> 118 119 #include <xen/xenbus/xenbusvar.h> 120 121 bool xen_suspend_cancelled; 122 /*--------------------------- Forward Declarations --------------------------*/ 123 /** Function signature for shutdown event handlers. */ 124 typedef void (xctrl_shutdown_handler_t)(void); 125 126 static xctrl_shutdown_handler_t xctrl_poweroff; 127 static xctrl_shutdown_handler_t xctrl_reboot; 128 static xctrl_shutdown_handler_t xctrl_suspend; 129 static xctrl_shutdown_handler_t xctrl_crash; 130 131 /*-------------------------- Private Data Structures -------------------------*/ 132 /** Element type for lookup table of event name to handler. */ 133 struct xctrl_shutdown_reason { 134 const char *name; 135 xctrl_shutdown_handler_t *handler; 136 }; 137 138 /** Lookup table for shutdown event name to handler. */ 139 static const struct xctrl_shutdown_reason xctrl_shutdown_reasons[] = { 140 { "poweroff", xctrl_poweroff }, 141 { "reboot", xctrl_reboot }, 142 { "suspend", xctrl_suspend }, 143 { "crash", xctrl_crash }, 144 { "halt", xctrl_poweroff }, 145 }; 146 147 struct xctrl_softc { 148 struct xs_watch xctrl_watch; 149 }; 150 151 /*------------------------------ Event Handlers ------------------------------*/ 152 static void 153 xctrl_poweroff(void) 154 { 155 shutdown_nice(RB_POWEROFF|RB_HALT); 156 } 157 158 static void 159 xctrl_reboot(void) 160 { 161 shutdown_nice(0); 162 } 163 164 #if !defined(__amd64__) && !defined(__i386__) 165 static void 166 xctrl_suspend(void) 167 { 168 printf("WARNING: xen/control: Suspend not supported!\n"); 169 } 170 #else /* __amd64__ || __i386__ */ 171 static void 172 xctrl_suspend(void) 173 { 174 #ifdef SMP 175 cpuset_t cpu_suspend_map; 176 #endif 177 178 EVENTHANDLER_INVOKE(power_suspend_early); 179 xs_lock(); 180 stop_all_proc(); 181 xs_unlock(); 182 suspend_all_fs(); 183 EVENTHANDLER_INVOKE(power_suspend); 184 185 #ifdef EARLY_AP_STARTUP 186 MPASS(mp_ncpus == 1 || smp_started); 187 thread_lock(curthread); 188 sched_bind(curthread, 0); 189 thread_unlock(curthread); 190 #else 191 if (smp_started) { 192 thread_lock(curthread); 193 sched_bind(curthread, 0); 194 thread_unlock(curthread); 195 } 196 #endif 197 KASSERT((PCPU_GET(cpuid) == 0), ("Not running on CPU#0")); 198 199 /* 200 * Be sure to hold Giant across DEVICE_SUSPEND/RESUME. 201 */ 202 bus_topo_lock(); 203 if (DEVICE_SUSPEND(root_bus) != 0) { 204 bus_topo_unlock(); 205 printf("%s: device_suspend failed\n", __func__); 206 return; 207 } 208 209 #ifdef SMP 210 #ifdef EARLY_AP_STARTUP 211 /* 212 * Suspend other CPUs. This prevents IPIs while we 213 * are resuming, and will allow us to reset per-cpu 214 * vcpu_info on resume. 215 */ 216 cpu_suspend_map = all_cpus; 217 CPU_CLR(PCPU_GET(cpuid), &cpu_suspend_map); 218 if (!CPU_EMPTY(&cpu_suspend_map)) 219 suspend_cpus(cpu_suspend_map); 220 #else 221 CPU_ZERO(&cpu_suspend_map); /* silence gcc */ 222 if (smp_started) { 223 /* 224 * Suspend other CPUs. This prevents IPIs while we 225 * are resuming, and will allow us to reset per-cpu 226 * vcpu_info on resume. 227 */ 228 cpu_suspend_map = all_cpus; 229 CPU_CLR(PCPU_GET(cpuid), &cpu_suspend_map); 230 if (!CPU_EMPTY(&cpu_suspend_map)) 231 suspend_cpus(cpu_suspend_map); 232 } 233 #endif 234 #endif 235 236 /* 237 * Prevent any races with evtchn_interrupt() handler. 238 */ 239 disable_intr(); 240 intr_suspend(); 241 xen_hvm_suspend(); 242 243 xen_suspend_cancelled = !!HYPERVISOR_suspend(0); 244 245 if (!xen_suspend_cancelled) { 246 xen_hvm_resume(false); 247 } 248 intr_resume(xen_suspend_cancelled != 0); 249 enable_intr(); 250 251 /* 252 * Reset grant table info. 253 */ 254 if (!xen_suspend_cancelled) { 255 gnttab_resume(NULL); 256 } 257 258 #ifdef SMP 259 if (!CPU_EMPTY(&cpu_suspend_map)) { 260 /* 261 * Now that event channels have been initialized, 262 * resume CPUs. 263 */ 264 resume_cpus(cpu_suspend_map); 265 #if defined(__amd64__) || defined(__i386__) 266 /* Send an IPI_BITMAP in case there are pending bitmap IPIs. */ 267 lapic_ipi_vectored(IPI_BITMAP_VECTOR, APIC_IPI_DEST_ALL); 268 #endif 269 } 270 #endif 271 272 /* 273 * FreeBSD really needs to add DEVICE_SUSPEND_CANCEL or 274 * similar. 275 */ 276 DEVICE_RESUME(root_bus); 277 bus_topo_unlock(); 278 279 /* 280 * Warm up timecounter again and reset system clock. 281 */ 282 timecounter->tc_get_timecount(timecounter); 283 inittodr(time_second); 284 285 #ifdef EARLY_AP_STARTUP 286 thread_lock(curthread); 287 sched_unbind(curthread); 288 thread_unlock(curthread); 289 #else 290 if (smp_started) { 291 thread_lock(curthread); 292 sched_unbind(curthread); 293 thread_unlock(curthread); 294 } 295 #endif 296 297 resume_all_fs(); 298 resume_all_proc(); 299 300 EVENTHANDLER_INVOKE(power_resume); 301 302 if (bootverbose) 303 printf("System resumed after suspension\n"); 304 305 } 306 #endif /* __amd64__ || __i386__ */ 307 308 static void 309 xctrl_crash(void) 310 { 311 panic("Xen directed crash"); 312 } 313 314 static void 315 xctrl_shutdown_final(void *arg, int howto) 316 { 317 /* 318 * Inform the hypervisor that shutdown is complete, and specify the 319 * nature of the shutdown. RB_HALT is not handled by this function. 320 */ 321 if (KERNEL_PANICKED()) 322 HYPERVISOR_shutdown(SHUTDOWN_crash); 323 else if ((howto & RB_POWEROFF) != 0) 324 HYPERVISOR_shutdown(SHUTDOWN_poweroff); 325 else if ((howto & RB_HALT) == 0) 326 /* RB_POWERCYCLE or regular reset. */ 327 HYPERVISOR_shutdown(SHUTDOWN_reboot); 328 } 329 330 /*------------------------------ Event Reception -----------------------------*/ 331 static void 332 xctrl_on_watch_event(struct xs_watch *watch, const char **vec, unsigned int len) 333 { 334 const struct xctrl_shutdown_reason *reason; 335 const struct xctrl_shutdown_reason *last_reason; 336 char *result; 337 int error; 338 int result_len; 339 340 error = xs_read(XST_NIL, "control", "shutdown", 341 &result_len, (void **)&result); 342 if (error != 0 || result_len == 0) 343 return; 344 345 /* Acknowledge the request by writing back an empty string. */ 346 error = xs_write(XST_NIL, "control", "shutdown", ""); 347 if (error != 0) 348 printf("unable to ack shutdown request, proceeding anyway\n"); 349 350 reason = xctrl_shutdown_reasons; 351 last_reason = reason + nitems(xctrl_shutdown_reasons); 352 while (reason < last_reason) { 353 if (!strcmp(result, reason->name)) { 354 reason->handler(); 355 break; 356 } 357 reason++; 358 } 359 360 free(result, M_XENSTORE); 361 } 362 363 /*------------------ Private Device Attachment Functions --------------------*/ 364 365 static void 366 notify_support(void) 367 { 368 /* 369 * Notify kernel is ready to handle "control/shutdown" events. Ignore 370 * errors if the nodes haven't been created by the toolstack, as the 371 * parent "control" directory should be read-only for the guest. 372 */ 373 xs_write(XST_NIL, "control", "feature-poweroff", "1"); 374 xs_write(XST_NIL, "control", "feature-reboot", "1"); 375 xs_write(XST_NIL, "control", "feature-suspend", "1"); 376 } 377 378 /** 379 * \brief Identify instances of this device type in the system. 380 * 381 * \param driver The driver performing this identify action. 382 * \param parent The NewBus parent device for any devices this method adds. 383 */ 384 static void 385 xctrl_identify(driver_t *driver, device_t parent) 386 { 387 /* 388 * A single device instance for our driver is always present 389 * in a system operating under Xen. 390 */ 391 BUS_ADD_CHILD(parent, 0, driver->name, 0); 392 } 393 394 /** 395 * \brief Probe for the existence of the Xen Control device 396 * 397 * \param dev NewBus device_t for this Xen control instance. 398 * 399 * \return Always returns 0 indicating success. 400 */ 401 static int 402 xctrl_probe(device_t dev) 403 { 404 device_set_desc(dev, "Xen Control Device"); 405 406 return (BUS_PROBE_NOWILDCARD); 407 } 408 409 /** 410 * \brief Attach the Xen control device. 411 * 412 * \param dev NewBus device_t for this Xen control instance. 413 * 414 * \return On success, 0. Otherwise an errno value indicating the 415 * type of failure. 416 */ 417 static int 418 xctrl_attach(device_t dev) 419 { 420 struct xctrl_softc *xctrl; 421 422 xctrl = device_get_softc(dev); 423 424 /* Activate watch */ 425 xctrl->xctrl_watch.node = "control/shutdown"; 426 xctrl->xctrl_watch.callback = xctrl_on_watch_event; 427 xctrl->xctrl_watch.callback_data = (uintptr_t)xctrl; 428 /* 429 * We don't care about the path updated, just about the value changes 430 * on that single node, hence there's no need to queue more that one 431 * event. 432 */ 433 xctrl->xctrl_watch.max_pending = 1; 434 xs_register_watch(&xctrl->xctrl_watch); 435 436 EVENTHANDLER_REGISTER(shutdown_final, xctrl_shutdown_final, NULL, 437 SHUTDOWN_PRI_LAST); 438 439 notify_support(); 440 441 return (0); 442 } 443 444 /** 445 * \brief Detach the Xen control device. 446 * 447 * \param dev NewBus device_t for this Xen control device instance. 448 * 449 * \return On success, 0. Otherwise an errno value indicating the 450 * type of failure. 451 */ 452 static int 453 xctrl_detach(device_t dev) 454 { 455 struct xctrl_softc *xctrl; 456 457 xctrl = device_get_softc(dev); 458 459 /* Release watch */ 460 xs_unregister_watch(&xctrl->xctrl_watch); 461 462 return (0); 463 } 464 465 static int 466 xctrl_resume(device_t dev) 467 { 468 notify_support(); 469 470 return (0); 471 } 472 473 /*-------------------- Private Device Attachment Data -----------------------*/ 474 static device_method_t xctrl_methods[] = { 475 /* Device interface */ 476 DEVMETHOD(device_identify, xctrl_identify), 477 DEVMETHOD(device_probe, xctrl_probe), 478 DEVMETHOD(device_attach, xctrl_attach), 479 DEVMETHOD(device_detach, xctrl_detach), 480 DEVMETHOD(device_resume, xctrl_resume), 481 482 DEVMETHOD_END 483 }; 484 485 DEFINE_CLASS_0(xctrl, xctrl_driver, xctrl_methods, sizeof(struct xctrl_softc)); 486 487 DRIVER_MODULE(xctrl, xenstore, xctrl_driver, NULL, NULL); 488