1 /* 2 * Copyright (c) 2013 Roger Pau Monné <[email protected]> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/bus.h> 33 #include <sys/kernel.h> 34 #include <sys/module.h> 35 #include <sys/pcpu.h> 36 #include <sys/smp.h> 37 38 #include <xen/xen-os.h> 39 40 /* 41 * Dummy Xen cpu device 42 * 43 * Since there's no ACPI on PVH guests, we need to create a dummy 44 * CPU device in order to fill the pcpu->pc_device field. 45 */ 46 47 static void 48 xenpvcpu_identify(driver_t *driver, device_t parent) 49 { 50 int i; 51 52 /* Only attach in case the per-CPU device is not set. */ 53 if (!xen_domain() || PCPU_GET(device) != NULL) 54 return; 55 56 CPU_FOREACH(i) { 57 if (BUS_ADD_CHILD(parent, 0, "pvcpu", i) == NULL) 58 panic("Unable to add Xen PV CPU device."); 59 } 60 } 61 62 static int 63 xenpvcpu_probe(device_t dev) 64 { 65 66 device_set_desc(dev, "Xen PV CPU"); 67 return (BUS_PROBE_NOWILDCARD); 68 } 69 70 static int 71 xenpvcpu_attach(device_t dev) 72 { 73 struct pcpu *pc; 74 int cpu; 75 76 cpu = device_get_unit(dev); 77 pc = pcpu_find(cpu); 78 pc->pc_device = dev; 79 return (0); 80 } 81 82 static device_method_t xenpvcpu_methods[] = { 83 DEVMETHOD(device_identify, xenpvcpu_identify), 84 DEVMETHOD(device_probe, xenpvcpu_probe), 85 DEVMETHOD(device_attach, xenpvcpu_attach), 86 87 DEVMETHOD_END 88 }; 89 90 static driver_t xenpvcpu_driver = { 91 "pvcpu", 92 xenpvcpu_methods, 93 0, 94 }; 95 96 devclass_t xenpvcpu_devclass; 97 98 DRIVER_MODULE(xenpvcpu, xenpv, xenpvcpu_driver, xenpvcpu_devclass, 0, 0); 99 MODULE_DEPEND(xenpvcpu, xenpv, 1, 1, 1); 100