1ff662b5cSJustin T. Gibbs /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause AND BSD-4-Clause 3718cf2ccSPedro F. Giffuni * 4ff662b5cSJustin T. Gibbs * Copyright (c) 2010 Justin T. Gibbs, Spectra Logic Corporation 5ff662b5cSJustin T. Gibbs * All rights reserved. 6ff662b5cSJustin T. Gibbs * 7ff662b5cSJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 8ff662b5cSJustin T. Gibbs * modification, are permitted provided that the following conditions 9ff662b5cSJustin T. Gibbs * are met: 10ff662b5cSJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 11ff662b5cSJustin T. Gibbs * notice, this list of conditions, and the following disclaimer, 12ff662b5cSJustin T. Gibbs * without modification. 13ff662b5cSJustin T. Gibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14ff662b5cSJustin T. Gibbs * substantially similar to the "NO WARRANTY" disclaimer below 15ff662b5cSJustin T. Gibbs * ("Disclaimer") and any redistribution must be conditioned upon 16ff662b5cSJustin T. Gibbs * including a substantially similar Disclaimer requirement for further 17ff662b5cSJustin T. Gibbs * binary redistribution. 18ff662b5cSJustin T. Gibbs * 19ff662b5cSJustin T. Gibbs * NO WARRANTY 20ff662b5cSJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21ff662b5cSJustin T. Gibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22ff662b5cSJustin T. Gibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 23ff662b5cSJustin T. Gibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24ff662b5cSJustin T. Gibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25ff662b5cSJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26ff662b5cSJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27ff662b5cSJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28ff662b5cSJustin T. Gibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29ff662b5cSJustin T. Gibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30ff662b5cSJustin T. Gibbs * POSSIBILITY OF SUCH DAMAGES. 31ff662b5cSJustin T. Gibbs */ 32ff662b5cSJustin T. Gibbs 33ff662b5cSJustin T. Gibbs /*- 34ff662b5cSJustin T. Gibbs * PV suspend/resume support: 35ff662b5cSJustin T. Gibbs * 36ff662b5cSJustin T. Gibbs * Copyright (c) 2004 Christian Limpach. 37ff662b5cSJustin T. Gibbs * Copyright (c) 2004-2006,2008 Kip Macy 38ff662b5cSJustin T. Gibbs * All rights reserved. 39ff662b5cSJustin T. Gibbs * 40ff662b5cSJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 41ff662b5cSJustin T. Gibbs * modification, are permitted provided that the following conditions 42ff662b5cSJustin T. Gibbs * are met: 43ff662b5cSJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 44ff662b5cSJustin T. Gibbs * notice, this list of conditions and the following disclaimer. 45ff662b5cSJustin T. Gibbs * 2. Redistributions in binary form must reproduce the above copyright 46ff662b5cSJustin T. Gibbs * notice, this list of conditions and the following disclaimer in the 47ff662b5cSJustin T. Gibbs * documentation and/or other materials provided with the distribution. 48ff662b5cSJustin T. Gibbs * 3. All advertising materials mentioning features or use of this software 49ff662b5cSJustin T. Gibbs * must display the following acknowledgement: 50ff662b5cSJustin T. Gibbs * This product includes software developed by Christian Limpach. 51ff662b5cSJustin T. Gibbs * 4. The name of the author may not be used to endorse or promote products 52ff662b5cSJustin T. Gibbs * derived from this software without specific prior written permission. 53ff662b5cSJustin T. Gibbs * 54ff662b5cSJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 55ff662b5cSJustin T. Gibbs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 56ff662b5cSJustin T. Gibbs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 57ff662b5cSJustin T. Gibbs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 58ff662b5cSJustin T. Gibbs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 59ff662b5cSJustin T. Gibbs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 60ff662b5cSJustin T. Gibbs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 61ff662b5cSJustin T. Gibbs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 62ff662b5cSJustin T. Gibbs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 63ff662b5cSJustin T. Gibbs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64ff662b5cSJustin T. Gibbs */ 65ff662b5cSJustin T. Gibbs 66ff662b5cSJustin T. Gibbs /*- 67ff662b5cSJustin T. Gibbs * HVM suspend/resume support: 68ff662b5cSJustin T. Gibbs * 69ff662b5cSJustin T. Gibbs * Copyright (c) 2008 Citrix Systems, Inc. 70ff662b5cSJustin T. Gibbs * All rights reserved. 71ff662b5cSJustin T. Gibbs * 72ff662b5cSJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 73ff662b5cSJustin T. Gibbs * modification, are permitted provided that the following conditions 74ff662b5cSJustin T. Gibbs * are met: 75ff662b5cSJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 76ff662b5cSJustin T. Gibbs * notice, this list of conditions and the following disclaimer. 77ff662b5cSJustin T. Gibbs * 2. Redistributions in binary form must reproduce the above copyright 78ff662b5cSJustin T. Gibbs * notice, this list of conditions and the following disclaimer in the 79ff662b5cSJustin T. Gibbs * documentation and/or other materials provided with the distribution. 80ff662b5cSJustin T. Gibbs * 81ff662b5cSJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 82ff662b5cSJustin T. Gibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 83ff662b5cSJustin T. Gibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 84ff662b5cSJustin T. Gibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 85ff662b5cSJustin T. Gibbs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 86ff662b5cSJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 87ff662b5cSJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 88ff662b5cSJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 89ff662b5cSJustin T. Gibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 90ff662b5cSJustin T. Gibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 91ff662b5cSJustin T. Gibbs * SUCH DAMAGE. 92ff662b5cSJustin T. Gibbs */ 93ff662b5cSJustin T. Gibbs #include <sys/cdefs.h> 94ff662b5cSJustin T. Gibbs /** 95ff662b5cSJustin T. Gibbs * \file control.c 96ff662b5cSJustin T. Gibbs * 97ff662b5cSJustin T. Gibbs * \brief Device driver to repond to control domain events that impact 98ff662b5cSJustin T. Gibbs * this VM. 99ff662b5cSJustin T. Gibbs */ 100ff662b5cSJustin T. Gibbs 101ff662b5cSJustin T. Gibbs #include <sys/param.h> 102ff662b5cSJustin T. Gibbs #include <sys/systm.h> 103ff662b5cSJustin T. Gibbs #include <sys/kernel.h> 104ff662b5cSJustin T. Gibbs #include <sys/malloc.h> 105ff662b5cSJustin T. Gibbs 106ff662b5cSJustin T. Gibbs #include <sys/bio.h> 107ff662b5cSJustin T. Gibbs #include <sys/bus.h> 108ff662b5cSJustin T. Gibbs #include <sys/conf.h> 109ff662b5cSJustin T. Gibbs #include <sys/disk.h> 110ff662b5cSJustin T. Gibbs #include <sys/fcntl.h> 111ff662b5cSJustin T. Gibbs #include <sys/filedesc.h> 112ff662b5cSJustin T. Gibbs #include <sys/kdb.h> 113ff662b5cSJustin T. Gibbs #include <sys/module.h> 114f1084587SKonstantin Belousov #include <sys/mount.h> 115ff662b5cSJustin T. Gibbs #include <sys/namei.h> 116ff662b5cSJustin T. Gibbs #include <sys/proc.h> 117ff662b5cSJustin T. Gibbs #include <sys/reboot.h> 118ff662b5cSJustin T. Gibbs #include <sys/rman.h> 1192ca7463bSJustin T. Gibbs #include <sys/sched.h> 120ff662b5cSJustin T. Gibbs #include <sys/taskqueue.h> 121ff662b5cSJustin T. Gibbs #include <sys/types.h> 122ff662b5cSJustin T. Gibbs #include <sys/vnode.h> 123ff662b5cSJustin T. Gibbs #include <sys/sched.h> 124ff662b5cSJustin T. Gibbs #include <sys/smp.h> 125428b7ca2SJustin T. Gibbs #include <sys/eventhandler.h> 1266e2a4a5fSRoger Pau Monné #include <sys/timetc.h> 127ff662b5cSJustin T. Gibbs 128ff662b5cSJustin T. Gibbs #include <geom/geom.h> 129ff662b5cSJustin T. Gibbs 130ff662b5cSJustin T. Gibbs #include <machine/_inttypes.h> 13146c46eddSJulien Grall #if defined(__amd64__) || defined(__i386__) 13276acc41fSJustin T. Gibbs #include <machine/intr_machdep.h> 133ff662b5cSJustin T. Gibbs 13415226522SRoger Pau Monné #include <x86/apicvar.h> 135d3705b5aSElliott Mitchell #endif 13615226522SRoger Pau Monné 137ff662b5cSJustin T. Gibbs #include <vm/vm.h> 138ff662b5cSJustin T. Gibbs #include <vm/vm_extern.h> 139ff662b5cSJustin T. Gibbs #include <vm/vm_kern.h> 140ff662b5cSJustin T. Gibbs 14176acc41fSJustin T. Gibbs #include <xen/xen-os.h> 142ff662b5cSJustin T. Gibbs #include <xen/blkif.h> 143ff662b5cSJustin T. Gibbs #include <xen/evtchn.h> 144ff662b5cSJustin T. Gibbs #include <xen/gnttab.h> 145ff662b5cSJustin T. Gibbs #include <xen/xen_intr.h> 146ff662b5cSJustin T. Gibbs 147428b7ca2SJustin T. Gibbs #include <xen/hvm.h> 148428b7ca2SJustin T. Gibbs 149ad7dd514SElliott Mitchell #include <contrib/xen/event_channel.h> 150ad7dd514SElliott Mitchell #include <contrib/xen/grant_table.h> 151ff662b5cSJustin T. Gibbs 152ff662b5cSJustin T. Gibbs #include <xen/xenbus/xenbusvar.h> 153ff662b5cSJustin T. Gibbs 1548dee0e9bSRoger Pau Monné bool xen_suspend_cancelled; 155ff662b5cSJustin T. Gibbs /*--------------------------- Forward Declarations --------------------------*/ 156ff662b5cSJustin T. Gibbs /** Function signature for shutdown event handlers. */ 157ff662b5cSJustin T. Gibbs typedef void (xctrl_shutdown_handler_t)(void); 158ff662b5cSJustin T. Gibbs 159ff662b5cSJustin T. Gibbs static xctrl_shutdown_handler_t xctrl_poweroff; 160ff662b5cSJustin T. Gibbs static xctrl_shutdown_handler_t xctrl_reboot; 161ff662b5cSJustin T. Gibbs static xctrl_shutdown_handler_t xctrl_suspend; 162ff662b5cSJustin T. Gibbs static xctrl_shutdown_handler_t xctrl_crash; 163ff662b5cSJustin T. Gibbs 164ff662b5cSJustin T. Gibbs /*-------------------------- Private Data Structures -------------------------*/ 165ff662b5cSJustin T. Gibbs /** Element type for lookup table of event name to handler. */ 166ff662b5cSJustin T. Gibbs struct xctrl_shutdown_reason { 167ff662b5cSJustin T. Gibbs const char *name; 168ff662b5cSJustin T. Gibbs xctrl_shutdown_handler_t *handler; 169ff662b5cSJustin T. Gibbs }; 170ff662b5cSJustin T. Gibbs 171ff662b5cSJustin T. Gibbs /** Lookup table for shutdown event name to handler. */ 172dcceabd3SMarius Strobl static const struct xctrl_shutdown_reason xctrl_shutdown_reasons[] = { 173ff662b5cSJustin T. Gibbs { "poweroff", xctrl_poweroff }, 174ff662b5cSJustin T. Gibbs { "reboot", xctrl_reboot }, 175ff662b5cSJustin T. Gibbs { "suspend", xctrl_suspend }, 176ff662b5cSJustin T. Gibbs { "crash", xctrl_crash }, 1774c85fcfaSJustin T. Gibbs { "halt", xctrl_poweroff }, 178ff662b5cSJustin T. Gibbs }; 179ff662b5cSJustin T. Gibbs 180ff662b5cSJustin T. Gibbs struct xctrl_softc { 181ff662b5cSJustin T. Gibbs struct xs_watch xctrl_watch; 182ff662b5cSJustin T. Gibbs }; 183ff662b5cSJustin T. Gibbs 184ff662b5cSJustin T. Gibbs /*------------------------------ Event Handlers ------------------------------*/ 185ff662b5cSJustin T. Gibbs static void 186a6c80304SDimitry Andric xctrl_poweroff(void) 187ff662b5cSJustin T. Gibbs { 188ff662b5cSJustin T. Gibbs shutdown_nice(RB_POWEROFF|RB_HALT); 189ff662b5cSJustin T. Gibbs } 190ff662b5cSJustin T. Gibbs 191ff662b5cSJustin T. Gibbs static void 192a6c80304SDimitry Andric xctrl_reboot(void) 193ff662b5cSJustin T. Gibbs { 194ff662b5cSJustin T. Gibbs shutdown_nice(0); 195ff662b5cSJustin T. Gibbs } 196ff662b5cSJustin T. Gibbs 19746c46eddSJulien Grall #if !defined(__amd64__) && !defined(__i386__) 19846c46eddSJulien Grall static void 199a6c80304SDimitry Andric xctrl_suspend(void) 20046c46eddSJulien Grall { 20146c46eddSJulien Grall printf("WARNING: xen/control: Suspend not supported!\n"); 20246c46eddSJulien Grall } 20346c46eddSJulien Grall #else /* __amd64__ || __i386__ */ 204ff662b5cSJustin T. Gibbs static void 205a6c80304SDimitry Andric xctrl_suspend(void) 206ff662b5cSJustin T. Gibbs { 207428b7ca2SJustin T. Gibbs #ifdef SMP 208428b7ca2SJustin T. Gibbs cpuset_t cpu_suspend_map; 209428b7ca2SJustin T. Gibbs #endif 210ff662b5cSJustin T. Gibbs 2116e2a4a5fSRoger Pau Monné EVENTHANDLER_INVOKE(power_suspend_early); 21241716b8dSRoger Pau Monné xs_lock(); 2136e2a4a5fSRoger Pau Monné stop_all_proc(); 21441716b8dSRoger Pau Monné xs_unlock(); 215f1084587SKonstantin Belousov suspend_all_fs(); 2162ca7463bSJustin T. Gibbs EVENTHANDLER_INVOKE(power_suspend); 2172ca7463bSJustin T. Gibbs 218fdce57a0SJohn Baldwin #ifdef EARLY_AP_STARTUP 219fdce57a0SJohn Baldwin MPASS(mp_ncpus == 1 || smp_started); 220fdce57a0SJohn Baldwin thread_lock(curthread); 221fdce57a0SJohn Baldwin sched_bind(curthread, 0); 222fdce57a0SJohn Baldwin thread_unlock(curthread); 223fdce57a0SJohn Baldwin #else 224428b7ca2SJustin T. Gibbs if (smp_started) { 225428b7ca2SJustin T. Gibbs thread_lock(curthread); 226428b7ca2SJustin T. Gibbs sched_bind(curthread, 0); 227428b7ca2SJustin T. Gibbs thread_unlock(curthread); 228428b7ca2SJustin T. Gibbs } 229fdce57a0SJohn Baldwin #endif 230428b7ca2SJustin T. Gibbs KASSERT((PCPU_GET(cpuid) == 0), ("Not running on CPU#0")); 231428b7ca2SJustin T. Gibbs 232428b7ca2SJustin T. Gibbs /* 233c6df6f53SWarner Losh * Be sure to hold Giant across DEVICE_SUSPEND/RESUME. 2342ca7463bSJustin T. Gibbs */ 235c6df6f53SWarner Losh bus_topo_lock(); 236dcceabd3SMarius Strobl if (DEVICE_SUSPEND(root_bus) != 0) { 237c6df6f53SWarner Losh bus_topo_unlock(); 238dcceabd3SMarius Strobl printf("%s: device_suspend failed\n", __func__); 239ff662b5cSJustin T. Gibbs return; 240ff662b5cSJustin T. Gibbs } 241ff662b5cSJustin T. Gibbs 242428b7ca2SJustin T. Gibbs #ifdef SMP 243fdce57a0SJohn Baldwin #ifdef EARLY_AP_STARTUP 244fdce57a0SJohn Baldwin /* 245fdce57a0SJohn Baldwin * Suspend other CPUs. This prevents IPIs while we 246fdce57a0SJohn Baldwin * are resuming, and will allow us to reset per-cpu 247fdce57a0SJohn Baldwin * vcpu_info on resume. 248fdce57a0SJohn Baldwin */ 249fdce57a0SJohn Baldwin cpu_suspend_map = all_cpus; 250fdce57a0SJohn Baldwin CPU_CLR(PCPU_GET(cpuid), &cpu_suspend_map); 251fdce57a0SJohn Baldwin if (!CPU_EMPTY(&cpu_suspend_map)) 252fdce57a0SJohn Baldwin suspend_cpus(cpu_suspend_map); 253fdce57a0SJohn Baldwin #else 254faf8ff5fSDimitry Andric CPU_ZERO(&cpu_suspend_map); /* silence gcc */ 255428b7ca2SJustin T. Gibbs if (smp_started) { 256428b7ca2SJustin T. Gibbs /* 257428b7ca2SJustin T. Gibbs * Suspend other CPUs. This prevents IPIs while we 258428b7ca2SJustin T. Gibbs * are resuming, and will allow us to reset per-cpu 259428b7ca2SJustin T. Gibbs * vcpu_info on resume. 260428b7ca2SJustin T. Gibbs */ 261428b7ca2SJustin T. Gibbs cpu_suspend_map = all_cpus; 262428b7ca2SJustin T. Gibbs CPU_CLR(PCPU_GET(cpuid), &cpu_suspend_map); 263428b7ca2SJustin T. Gibbs if (!CPU_EMPTY(&cpu_suspend_map)) 264428b7ca2SJustin T. Gibbs suspend_cpus(cpu_suspend_map); 265428b7ca2SJustin T. Gibbs } 266428b7ca2SJustin T. Gibbs #endif 267fdce57a0SJohn Baldwin #endif 268428b7ca2SJustin T. Gibbs 269ff662b5cSJustin T. Gibbs /* 270ff662b5cSJustin T. Gibbs * Prevent any races with evtchn_interrupt() handler. 271ff662b5cSJustin T. Gibbs */ 272ff662b5cSJustin T. Gibbs disable_intr(); 27376acc41fSJustin T. Gibbs intr_suspend(); 274428b7ca2SJustin T. Gibbs xen_hvm_suspend(); 275ff662b5cSJustin T. Gibbs 2768dee0e9bSRoger Pau Monné xen_suspend_cancelled = !!HYPERVISOR_suspend(0); 27776acc41fSJustin T. Gibbs 2788dee0e9bSRoger Pau Monné if (!xen_suspend_cancelled) { 2798dee0e9bSRoger Pau Monné xen_hvm_resume(false); 2808dee0e9bSRoger Pau Monné } 2818dee0e9bSRoger Pau Monné intr_resume(xen_suspend_cancelled != 0); 282428b7ca2SJustin T. Gibbs enable_intr(); 283ff662b5cSJustin T. Gibbs 284ff662b5cSJustin T. Gibbs /* 285428b7ca2SJustin T. Gibbs * Reset grant table info. 286ff662b5cSJustin T. Gibbs */ 2878dee0e9bSRoger Pau Monné if (!xen_suspend_cancelled) { 288a8f2f559SRoger Pau Monné gnttab_resume(NULL); 2898dee0e9bSRoger Pau Monné } 290428b7ca2SJustin T. Gibbs 291428b7ca2SJustin T. Gibbs #ifdef SMP 292b406166fSJohn Baldwin if (!CPU_EMPTY(&cpu_suspend_map)) { 293428b7ca2SJustin T. Gibbs /* 294428b7ca2SJustin T. Gibbs * Now that event channels have been initialized, 295428b7ca2SJustin T. Gibbs * resume CPUs. 296428b7ca2SJustin T. Gibbs */ 297428b7ca2SJustin T. Gibbs resume_cpus(cpu_suspend_map); 298d3705b5aSElliott Mitchell #if defined(__amd64__) || defined(__i386__) 2994ea0b4adSRoger Pau Monné /* Send an IPI_BITMAP in case there are pending bitmap IPIs. */ 3004ea0b4adSRoger Pau Monné lapic_ipi_vectored(IPI_BITMAP_VECTOR, APIC_IPI_DEST_ALL); 301d3705b5aSElliott Mitchell #endif 302428b7ca2SJustin T. Gibbs } 303428b7ca2SJustin T. Gibbs #endif 304ff662b5cSJustin T. Gibbs 305ff662b5cSJustin T. Gibbs /* 306ff662b5cSJustin T. Gibbs * FreeBSD really needs to add DEVICE_SUSPEND_CANCEL or 307ff662b5cSJustin T. Gibbs * similar. 308ff662b5cSJustin T. Gibbs */ 309ff662b5cSJustin T. Gibbs DEVICE_RESUME(root_bus); 310c6df6f53SWarner Losh bus_topo_unlock(); 3112ca7463bSJustin T. Gibbs 3126e2a4a5fSRoger Pau Monné /* 3136e2a4a5fSRoger Pau Monné * Warm up timecounter again and reset system clock. 3146e2a4a5fSRoger Pau Monné */ 3156e2a4a5fSRoger Pau Monné timecounter->tc_get_timecount(timecounter); 3166e2a4a5fSRoger Pau Monné inittodr(time_second); 3176e2a4a5fSRoger Pau Monné 318fdce57a0SJohn Baldwin #ifdef EARLY_AP_STARTUP 319fdce57a0SJohn Baldwin thread_lock(curthread); 320fdce57a0SJohn Baldwin sched_unbind(curthread); 321fdce57a0SJohn Baldwin thread_unlock(curthread); 322fdce57a0SJohn Baldwin #else 323428b7ca2SJustin T. Gibbs if (smp_started) { 324428b7ca2SJustin T. Gibbs thread_lock(curthread); 325428b7ca2SJustin T. Gibbs sched_unbind(curthread); 326428b7ca2SJustin T. Gibbs thread_unlock(curthread); 327428b7ca2SJustin T. Gibbs } 328fdce57a0SJohn Baldwin #endif 329428b7ca2SJustin T. Gibbs 330f1084587SKonstantin Belousov resume_all_fs(); 3316e2a4a5fSRoger Pau Monné resume_all_proc(); 3326e2a4a5fSRoger Pau Monné 3332ca7463bSJustin T. Gibbs EVENTHANDLER_INVOKE(power_resume); 334428b7ca2SJustin T. Gibbs 335428b7ca2SJustin T. Gibbs if (bootverbose) 336428b7ca2SJustin T. Gibbs printf("System resumed after suspension\n"); 337428b7ca2SJustin T. Gibbs 338ff662b5cSJustin T. Gibbs } 33946c46eddSJulien Grall #endif /* __amd64__ || __i386__ */ 340ff662b5cSJustin T. Gibbs 341ff662b5cSJustin T. Gibbs static void 342a6c80304SDimitry Andric xctrl_crash(void) 343ff662b5cSJustin T. Gibbs { 344ff662b5cSJustin T. Gibbs panic("Xen directed crash"); 345ff662b5cSJustin T. Gibbs } 346ff662b5cSJustin T. Gibbs 347bd851e63SRoger Pau Monné static void 3489e0b0f5dSMitchell Horne xctrl_shutdown_final(void *arg, int howto) 349bd851e63SRoger Pau Monné { 3509e0b0f5dSMitchell Horne /* 3519e0b0f5dSMitchell Horne * Inform the hypervisor that shutdown is complete, and specify the 3529e0b0f5dSMitchell Horne * nature of the shutdown. RB_HALT is not handled by this function. 3539e0b0f5dSMitchell Horne */ 3549e0b0f5dSMitchell Horne if (KERNEL_PANICKED()) 3559e0b0f5dSMitchell Horne HYPERVISOR_shutdown(SHUTDOWN_crash); 3569e0b0f5dSMitchell Horne else if ((howto & RB_POWEROFF) != 0) 357bd851e63SRoger Pau Monné HYPERVISOR_shutdown(SHUTDOWN_poweroff); 3589e0b0f5dSMitchell Horne else if ((howto & RB_HALT) == 0) 3599e0b0f5dSMitchell Horne /* RB_POWERCYCLE or regular reset. */ 360bd851e63SRoger Pau Monné HYPERVISOR_shutdown(SHUTDOWN_reboot); 361bd851e63SRoger Pau Monné } 362bd851e63SRoger Pau Monné 363ff662b5cSJustin T. Gibbs /*------------------------------ Event Reception -----------------------------*/ 364ff662b5cSJustin T. Gibbs static void 365ff662b5cSJustin T. Gibbs xctrl_on_watch_event(struct xs_watch *watch, const char **vec, unsigned int len) 366ff662b5cSJustin T. Gibbs { 367dcceabd3SMarius Strobl const struct xctrl_shutdown_reason *reason; 368dcceabd3SMarius Strobl const struct xctrl_shutdown_reason *last_reason; 369ff662b5cSJustin T. Gibbs char *result; 370ff662b5cSJustin T. Gibbs int error; 371ff662b5cSJustin T. Gibbs int result_len; 372ff662b5cSJustin T. Gibbs 373ff662b5cSJustin T. Gibbs error = xs_read(XST_NIL, "control", "shutdown", 374ff662b5cSJustin T. Gibbs &result_len, (void **)&result); 37506592d60SRoger Pau Monné if (error != 0 || result_len == 0) 376ff662b5cSJustin T. Gibbs return; 377ff662b5cSJustin T. Gibbs 37806798cf5SRoger Pau Monné /* Acknowledge the request by writing back an empty string. */ 37906798cf5SRoger Pau Monné error = xs_write(XST_NIL, "control", "shutdown", ""); 38006798cf5SRoger Pau Monné if (error != 0) 38106798cf5SRoger Pau Monné printf("unable to ack shutdown request, proceeding anyway\n"); 38206798cf5SRoger Pau Monné 383ff662b5cSJustin T. Gibbs reason = xctrl_shutdown_reasons; 384dcceabd3SMarius Strobl last_reason = reason + nitems(xctrl_shutdown_reasons); 385ff662b5cSJustin T. Gibbs while (reason < last_reason) { 386ff662b5cSJustin T. Gibbs if (!strcmp(result, reason->name)) { 387ff662b5cSJustin T. Gibbs reason->handler(); 388ff662b5cSJustin T. Gibbs break; 389ff662b5cSJustin T. Gibbs } 390ff662b5cSJustin T. Gibbs reason++; 391ff662b5cSJustin T. Gibbs } 392ff662b5cSJustin T. Gibbs 393ff662b5cSJustin T. Gibbs free(result, M_XENSTORE); 394ff662b5cSJustin T. Gibbs } 395ff662b5cSJustin T. Gibbs 396ff662b5cSJustin T. Gibbs /*------------------ Private Device Attachment Functions --------------------*/ 397ff662b5cSJustin T. Gibbs /** 398ff662b5cSJustin T. Gibbs * \brief Identify instances of this device type in the system. 399ff662b5cSJustin T. Gibbs * 400ff662b5cSJustin T. Gibbs * \param driver The driver performing this identify action. 401ff662b5cSJustin T. Gibbs * \param parent The NewBus parent device for any devices this method adds. 402ff662b5cSJustin T. Gibbs */ 403ff662b5cSJustin T. Gibbs static void 404*d48760ffSElliott Mitchell xctrl_identify(driver_t *driver, device_t parent) 405ff662b5cSJustin T. Gibbs { 406ff662b5cSJustin T. Gibbs /* 407ff662b5cSJustin T. Gibbs * A single device instance for our driver is always present 408ff662b5cSJustin T. Gibbs * in a system operating under Xen. 409ff662b5cSJustin T. Gibbs */ 410ff662b5cSJustin T. Gibbs BUS_ADD_CHILD(parent, 0, driver->name, 0); 411ff662b5cSJustin T. Gibbs } 412ff662b5cSJustin T. Gibbs 413ff662b5cSJustin T. Gibbs /** 414453130d9SPedro F. Giffuni * \brief Probe for the existence of the Xen Control device 415ff662b5cSJustin T. Gibbs * 416ff662b5cSJustin T. Gibbs * \param dev NewBus device_t for this Xen control instance. 417ff662b5cSJustin T. Gibbs * 418ff662b5cSJustin T. Gibbs * \return Always returns 0 indicating success. 419ff662b5cSJustin T. Gibbs */ 420ff662b5cSJustin T. Gibbs static int 421ff662b5cSJustin T. Gibbs xctrl_probe(device_t dev) 422ff662b5cSJustin T. Gibbs { 423ff662b5cSJustin T. Gibbs device_set_desc(dev, "Xen Control Device"); 424ff662b5cSJustin T. Gibbs 4252f9ec994SRoger Pau Monné return (BUS_PROBE_NOWILDCARD); 426ff662b5cSJustin T. Gibbs } 427ff662b5cSJustin T. Gibbs 428ff662b5cSJustin T. Gibbs /** 429ff662b5cSJustin T. Gibbs * \brief Attach the Xen control device. 430ff662b5cSJustin T. Gibbs * 431ff662b5cSJustin T. Gibbs * \param dev NewBus device_t for this Xen control instance. 432ff662b5cSJustin T. Gibbs * 433ff662b5cSJustin T. Gibbs * \return On success, 0. Otherwise an errno value indicating the 434ff662b5cSJustin T. Gibbs * type of failure. 435ff662b5cSJustin T. Gibbs */ 436ff662b5cSJustin T. Gibbs static int 437ff662b5cSJustin T. Gibbs xctrl_attach(device_t dev) 438ff662b5cSJustin T. Gibbs { 439ff662b5cSJustin T. Gibbs struct xctrl_softc *xctrl; 440ff662b5cSJustin T. Gibbs 441ff662b5cSJustin T. Gibbs xctrl = device_get_softc(dev); 442ff662b5cSJustin T. Gibbs 443ff662b5cSJustin T. Gibbs /* Activate watch */ 444ff662b5cSJustin T. Gibbs xctrl->xctrl_watch.node = "control/shutdown"; 445ff662b5cSJustin T. Gibbs xctrl->xctrl_watch.callback = xctrl_on_watch_event; 446283d6f72SJustin T. Gibbs xctrl->xctrl_watch.callback_data = (uintptr_t)xctrl; 4474e4e43dcSRoger Pau Monné /* 4484e4e43dcSRoger Pau Monné * We don't care about the path updated, just about the value changes 4494e4e43dcSRoger Pau Monné * on that single node, hence there's no need to queue more that one 4504e4e43dcSRoger Pau Monné * event. 4514e4e43dcSRoger Pau Monné */ 4524e4e43dcSRoger Pau Monné xctrl->xctrl_watch.max_pending = 1; 453ff662b5cSJustin T. Gibbs xs_register_watch(&xctrl->xctrl_watch); 454ff662b5cSJustin T. Gibbs 4559e0b0f5dSMitchell Horne EVENTHANDLER_REGISTER(shutdown_final, xctrl_shutdown_final, NULL, 456ff662b5cSJustin T. Gibbs SHUTDOWN_PRI_LAST); 457ff662b5cSJustin T. Gibbs 458ff662b5cSJustin T. Gibbs return (0); 459ff662b5cSJustin T. Gibbs } 460ff662b5cSJustin T. Gibbs 461ff662b5cSJustin T. Gibbs /** 462ff662b5cSJustin T. Gibbs * \brief Detach the Xen control device. 463ff662b5cSJustin T. Gibbs * 464ff662b5cSJustin T. Gibbs * \param dev NewBus device_t for this Xen control device instance. 465ff662b5cSJustin T. Gibbs * 466ff662b5cSJustin T. Gibbs * \return On success, 0. Otherwise an errno value indicating the 467ff662b5cSJustin T. Gibbs * type of failure. 468ff662b5cSJustin T. Gibbs */ 469ff662b5cSJustin T. Gibbs static int 470ff662b5cSJustin T. Gibbs xctrl_detach(device_t dev) 471ff662b5cSJustin T. Gibbs { 472ff662b5cSJustin T. Gibbs struct xctrl_softc *xctrl; 473ff662b5cSJustin T. Gibbs 474ff662b5cSJustin T. Gibbs xctrl = device_get_softc(dev); 475ff662b5cSJustin T. Gibbs 476ff662b5cSJustin T. Gibbs /* Release watch */ 477ff662b5cSJustin T. Gibbs xs_unregister_watch(&xctrl->xctrl_watch); 478ff662b5cSJustin T. Gibbs 479ff662b5cSJustin T. Gibbs return (0); 480ff662b5cSJustin T. Gibbs } 481ff662b5cSJustin T. Gibbs 482ff662b5cSJustin T. Gibbs /*-------------------- Private Device Attachment Data -----------------------*/ 483ff662b5cSJustin T. Gibbs static device_method_t xctrl_methods[] = { 484ff662b5cSJustin T. Gibbs /* Device interface */ 485ff662b5cSJustin T. Gibbs DEVMETHOD(device_identify, xctrl_identify), 486ff662b5cSJustin T. Gibbs DEVMETHOD(device_probe, xctrl_probe), 487ff662b5cSJustin T. Gibbs DEVMETHOD(device_attach, xctrl_attach), 488ff662b5cSJustin T. Gibbs DEVMETHOD(device_detach, xctrl_detach), 489ff662b5cSJustin T. Gibbs 490dcceabd3SMarius Strobl DEVMETHOD_END 491ff662b5cSJustin T. Gibbs }; 492ff662b5cSJustin T. Gibbs 493ff662b5cSJustin T. Gibbs DEFINE_CLASS_0(xctrl, xctrl_driver, xctrl_methods, sizeof(struct xctrl_softc)); 494ff662b5cSJustin T. Gibbs 495f929eb1eSJohn Baldwin DRIVER_MODULE(xctrl, xenstore, xctrl_driver, NULL, NULL); 496