diff options
Diffstat (limited to 'sys/dev/xen')
-rw-r--r-- | sys/dev/xen/blkback/blkback.c | 22 | ||||
-rw-r--r-- | sys/dev/xen/blkfront/blkfront.c | 51 | ||||
-rw-r--r-- | sys/dev/xen/bus/xen_intr.c | 2 | ||||
-rw-r--r-- | sys/dev/xen/bus/xenpv.c | 84 | ||||
-rw-r--r-- | sys/dev/xen/console/xen_console.c | 3 | ||||
-rw-r--r-- | sys/dev/xen/control/control.c | 60 | ||||
-rw-r--r-- | sys/dev/xen/debug/debug.c | 10 | ||||
-rw-r--r-- | sys/dev/xen/efi/pvefi.c | 6 | ||||
-rw-r--r-- | sys/dev/xen/gntdev/gntdev.c | 13 | ||||
-rw-r--r-- | sys/dev/xen/netfront/netfront.c | 38 | ||||
-rw-r--r-- | sys/dev/xen/pcifront/pcifront.c | 690 | ||||
-rw-r--r-- | sys/dev/xen/privcmd/privcmd.c | 14 | ||||
-rw-r--r-- | sys/dev/xen/xenpci/xenpci.c | 6 | ||||
-rw-r--r-- | sys/dev/xen/xenstore/xenstore.c | 11 |
14 files changed, 874 insertions, 136 deletions
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c index 3717264256f3..c6cba729b991 100644 --- a/sys/dev/xen/blkback/blkback.c +++ b/sys/dev/xen/blkback/blkback.c @@ -145,6 +145,8 @@ static MALLOC_DEFINE(M_XENBLOCKBACK, "xbbd", "Xen Block Back Driver Data"); */ #define XBB_MAX_SEGMENTS_PER_REQLIST XBB_MAX_SEGMENTS_PER_REQUEST +#define XBD_SECTOR_SHFT 9 + /*--------------------------- Forward Declarations ---------------------------*/ struct xbb_softc; struct xbb_xen_req; @@ -1150,7 +1152,9 @@ xbb_get_resources(struct xbb_softc *xbb, struct xbb_xen_reqlist **reqlist, if (*reqlist == NULL) { *reqlist = nreqlist; nreqlist->operation = ring_req->operation; - nreqlist->starting_sector_number = ring_req->sector_number; + nreqlist->starting_sector_number = + (ring_req->sector_number << XBD_SECTOR_SHFT) >> + xbb->sector_size_shift; STAILQ_INSERT_TAIL(&xbb->reqlist_pending_stailq, nreqlist, links); } @@ -2476,13 +2480,13 @@ xbb_open_file(struct xbb_softc *xbb) xbb->sector_size = 512; /* - * Sanity check. The media size has to be at least one - * sector long. + * Sanity check. The media size must be a multiple of the sector + * size. */ - if (xbb->media_size < xbb->sector_size) { + if ((xbb->media_size % xbb->sector_size) != 0) { error = EINVAL; xenbus_dev_fatal(xbb->dev, error, - "file %s size %ju < block size %u", + "file %s size %ju not multiple of block size %u", xbb->dev_name, (uintmax_t)xbb->media_size, xbb->sector_size); @@ -3086,9 +3090,13 @@ xbb_publish_backend_info(struct xbb_softc *xbb) return (error); } + /* + * The 'sectors' node is special and always contains the size + * in units of 512b, regardless of the value in 'sector-size'. + */ leaf = "sectors"; - error = xs_printf(xst, our_path, leaf, - "%"PRIu64, xbb->media_num_sectors); + error = xs_printf(xst, our_path, leaf, "%ju", + (uintmax_t)(xbb->media_size >> XBD_SECTOR_SHFT)); if (error != 0) break; diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c index 2c5862232b41..6bb4e32f1328 100644 --- a/sys/dev/xen/blkfront/blkfront.c +++ b/sys/dev/xen/blkfront/blkfront.c @@ -158,7 +158,8 @@ xbd_free_command(struct xbd_command *cm) static void xbd_mksegarray(bus_dma_segment_t *segs, int nsegs, grant_ref_t * gref_head, int otherend_id, int readonly, - grant_ref_t * sg_ref, struct blkif_request_segment *sg) + grant_ref_t * sg_ref, struct blkif_request_segment *sg, + unsigned int sector_size) { struct blkif_request_segment *last_block_sg = sg + nsegs; vm_paddr_t buffer_ma; @@ -166,9 +167,9 @@ xbd_mksegarray(bus_dma_segment_t *segs, int nsegs, int ref; while (sg < last_block_sg) { - KASSERT(segs->ds_addr % (1 << XBD_SECTOR_SHFT) == 0, + KASSERT((segs->ds_addr & (sector_size - 1)) == 0, ("XEN disk driver I/O must be sector aligned")); - KASSERT(segs->ds_len % (1 << XBD_SECTOR_SHFT) == 0, + KASSERT((segs->ds_len & (sector_size - 1)) == 0, ("XEN disk driver I/Os must be a multiple of " "the sector length")); buffer_ma = segs->ds_addr; @@ -241,7 +242,8 @@ xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) xbd_mksegarray(segs, nsegs, &cm->cm_gref_head, xenbus_get_otherend_id(sc->xbd_dev), cm->cm_operation == BLKIF_OP_WRITE, - cm->cm_sg_refs, ring_req->seg); + cm->cm_sg_refs, ring_req->seg, + sc->xbd_disk->d_sectorsize); } else { blkif_request_indirect_t *ring_req; @@ -259,7 +261,8 @@ xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) xbd_mksegarray(segs, nsegs, &cm->cm_gref_head, xenbus_get_otherend_id(sc->xbd_dev), cm->cm_operation == BLKIF_OP_WRITE, - cm->cm_sg_refs, cm->cm_indirectionpages); + cm->cm_sg_refs, cm->cm_indirectionpages, + sc->xbd_disk->d_sectorsize); memcpy(ring_req->indirect_grefs, &cm->cm_indirectionrefs, sizeof(grant_ref_t) * sc->xbd_max_request_indirectpages); } @@ -359,7 +362,9 @@ xbd_bio_command(struct xbd_softc *sc) } cm->cm_bp = bp; - cm->cm_sector_number = (blkif_sector_t)bp->bio_pblkno; + cm->cm_sector_number = + ((blkif_sector_t)bp->bio_pblkno * sc->xbd_disk->d_sectorsize) >> + XBD_SECTOR_SHFT; switch (bp->bio_cmd) { case BIO_READ: @@ -631,7 +636,7 @@ xbd_dump(void *arg, void *virtual, off_t offset, size_t length) cm->cm_data = virtual; cm->cm_datalen = chunk; cm->cm_operation = BLKIF_OP_WRITE; - cm->cm_sector_number = offset / dp->d_sectorsize; + cm->cm_sector_number = offset >> XBD_SECTOR_SHFT; cm->cm_complete = xbd_dump_complete; xbd_enqueue_cm(cm, XBD_Q_READY); @@ -1025,7 +1030,19 @@ xbd_instance_create(struct xbd_softc *sc, blkif_sector_t sectors, sc->xbd_disk->d_stripesize = phys_sector_size; sc->xbd_disk->d_stripeoffset = 0; - sc->xbd_disk->d_mediasize = sectors * sector_size; + /* + * The 'sectors' xenbus node is always in units of 512b, regardless of + * the 'sector-size' xenbus node value. + */ + sc->xbd_disk->d_mediasize = sectors << XBD_SECTOR_SHFT; + if ((sc->xbd_disk->d_mediasize % sc->xbd_disk->d_sectorsize) != 0) { + error = EINVAL; + xenbus_dev_fatal(sc->xbd_dev, error, + "Disk size (%ju) not a multiple of sector size (%ju)", + (uintmax_t)sc->xbd_disk->d_mediasize, + (uintmax_t)sc->xbd_disk->d_sectorsize); + return (error); + } sc->xbd_disk->d_maxsize = sc->xbd_max_request_size; sc->xbd_disk->d_flags = DISKFLAG_UNMAPPED_BIO; if ((sc->xbd_flags & (XBDF_FLUSH|XBDF_BARRIER)) != 0) { @@ -1064,9 +1081,7 @@ xbd_free(struct xbd_softc *sc) gnttab_end_foreign_access_references( sc->xbd_max_request_indirectpages, &cm->cm_indirectionrefs[0]); - contigfree(cm->cm_indirectionpages, PAGE_SIZE * - sc->xbd_max_request_indirectpages, - M_XENBLOCKFRONT); + free(cm->cm_indirectionpages, M_XENBLOCKFRONT); cm->cm_indirectionpages = NULL; } @@ -1312,7 +1327,7 @@ xbd_connect(struct xbd_softc *sc) /* Allocate datastructures based on negotiated values. */ err = bus_dma_tag_create( bus_get_dma_tag(sc->xbd_dev), /* parent */ - 512, PAGE_SIZE, /* algnmnt, boundary */ + sector_size, PAGE_SIZE, /* algnmnt, boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ @@ -1373,9 +1388,7 @@ xbd_connect(struct xbd_softc *sc) break; } if (j < sc->xbd_max_request_indirectpages) { - contigfree(indirectpages, - PAGE_SIZE * sc->xbd_max_request_indirectpages, - M_XENBLOCKFRONT); + free(indirectpages, M_XENBLOCKFRONT); break; } cm->cm_indirectionpages = indirectpages; @@ -1384,13 +1397,17 @@ xbd_connect(struct xbd_softc *sc) if (sc->xbd_disk == NULL) { device_printf(dev, "%juMB <%s> at %s", - (uintmax_t) sectors / (1048576 / sector_size), + (uintmax_t)((sectors << XBD_SECTOR_SHFT) / 1048576), device_get_desc(dev), xenbus_get_node(dev)); bus_print_child_footer(device_get_parent(dev), dev); - xbd_instance_create(sc, sectors, sc->xbd_vdevice, binfo, + err = xbd_instance_create(sc, sectors, sc->xbd_vdevice, binfo, sector_size, phys_sector_size); + if (err != 0) { + xenbus_dev_fatal(dev, err, "Unable to create instance"); + return; + } } (void)xenbus_set_state(dev, XenbusStateConnected); diff --git a/sys/dev/xen/bus/xen_intr.c b/sys/dev/xen/bus/xen_intr.c index bfe080b16f03..cb30b6efa484 100644 --- a/sys/dev/xen/bus/xen_intr.c +++ b/sys/dev/xen/bus/xen_intr.c @@ -45,12 +45,12 @@ #include <sys/proc.h> #include <sys/smp.h> #include <sys/refcount.h> +#include <sys/stdarg.h> #include <vm/vm.h> #include <vm/pmap.h> #include <machine/smp.h> -#include <machine/stdarg.h> #include <xen/xen-os.h> #include <xen/hypervisor.h> diff --git a/sys/dev/xen/bus/xenpv.c b/sys/dev/xen/bus/xenpv.c index 169e52f3a879..f710b0f91140 100644 --- a/sys/dev/xen/bus/xenpv.c +++ b/sys/dev/xen/bus/xenpv.c @@ -65,6 +65,16 @@ #define LOW_MEM_LIMIT 0 #endif +/* + * Memory ranges available for creating external mappings (foreign or grant + * pages for example). + */ +static struct rman unpopulated_mem = { + .rm_end = ~0, + .rm_type = RMAN_ARRAY, + .rm_descr = "Xen scratch memory", +}; + static void xenpv_identify(driver_t *driver, device_t parent) { @@ -91,23 +101,43 @@ xenpv_probe(device_t dev) return (BUS_PROBE_NOWILDCARD); } +/* Dummy init for arches that don't have a specific implementation. */ +int __weak_symbol +xen_arch_init_physmem(device_t dev, struct rman *mem) +{ + + return (0); +} + static int xenpv_attach(device_t dev) { - int error; + int error = rman_init(&unpopulated_mem); + + if (error != 0) + return (error); + + error = xen_arch_init_physmem(dev, &unpopulated_mem); + if (error != 0) + return (error); /* * Let our child drivers identify any child devices that they * can find. Once that is done attach any devices that we * found. */ - error = bus_generic_probe(dev); - if (error) - return (error); + bus_identify_children(dev); + bus_attach_children(dev); - error = bus_generic_attach(dev); + return (0); +} - return (error); +static int +release_unpopulated_mem(device_t dev, struct resource *res) +{ + + return (rman_is_region_manager(res, &unpopulated_mem) ? + rman_release_resource(res) : bus_release_resource(dev, res)); } static struct resource * @@ -117,17 +147,48 @@ xenpv_alloc_physmem(device_t dev, device_t child, int *res_id, size_t size) vm_paddr_t phys_addr; void *virt_addr; int error; + const unsigned int flags = RF_ACTIVE | RF_UNMAPPED | + RF_ALIGNMENT_LOG2(PAGE_SHIFT); + + KASSERT((size & PAGE_MASK) == 0, ("unaligned size requested")); + size = round_page(size); + + /* Attempt to allocate from arch resource manager. */ + res = rman_reserve_resource(&unpopulated_mem, 0, ~0, size, flags, + child); + if (res != NULL) { + rman_set_rid(res, *res_id); + rman_set_type(res, SYS_RES_MEMORY); + } else { + static bool warned = false; - res = bus_alloc_resource(child, SYS_RES_MEMORY, res_id, LOW_MEM_LIMIT, - ~0, size, RF_ACTIVE | RF_UNMAPPED); - if (res == NULL) + /* Fallback to generic MMIO allocator. */ + if (__predict_false(!warned)) { + warned = true; + device_printf(dev, + "unable to allocate from arch specific routine, " + "fall back to unused memory areas\n"); + } + res = bus_alloc_resource(child, SYS_RES_MEMORY, res_id, + LOW_MEM_LIMIT, ~0, size, flags); + } + + if (res == NULL) { + device_printf(dev, + "failed to allocate Xen unpopulated memory\n"); return (NULL); + } phys_addr = rman_get_start(res); error = vm_phys_fictitious_reg_range(phys_addr, phys_addr + size, VM_MEMATTR_XEN); if (error) { - bus_release_resource(child, SYS_RES_MEMORY, *res_id, res); + int error = release_unpopulated_mem(child, res); + + if (error != 0) + device_printf(dev, "failed to release resource: %d\n", + error); + return (NULL); } virt_addr = pmap_mapdev_attr(phys_addr, size, VM_MEMATTR_XEN); @@ -150,7 +211,8 @@ xenpv_free_physmem(device_t dev, device_t child, int res_id, struct resource *re pmap_unmapdev(virt_addr, size); vm_phys_fictitious_unreg_range(phys_addr, phys_addr + size); - return (bus_release_resource(child, SYS_RES_MEMORY, res_id, res)); + + return (release_unpopulated_mem(child, res)); } static device_method_t xenpv_methods[] = { diff --git a/sys/dev/xen/console/xen_console.c b/sys/dev/xen/console/xen_console.c index f1a298a2aefa..1d12d6caa257 100644 --- a/sys/dev/xen/console/xen_console.c +++ b/sys/dev/xen/console/xen_console.c @@ -42,8 +42,7 @@ #include <sys/kdb.h> #include <sys/proc.h> #include <sys/reboot.h> - -#include <machine/stdarg.h> +#include <sys/stdarg.h> #include <vm/vm.h> #include <vm/pmap.h> diff --git a/sys/dev/xen/control/control.c b/sys/dev/xen/control/control.c index 1dc1df935b84..123df4992894 100644 --- a/sys/dev/xen/control/control.c +++ b/sys/dev/xen/control/control.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause AND BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2010 Justin T. Gibbs, Spectra Logic Corporation * All rights reserved. @@ -31,39 +31,6 @@ */ /*- - * PV suspend/resume support: - * - * Copyright (c) 2004 Christian Limpach. - * Copyright (c) 2004-2006,2008 Kip Macy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christian Limpach. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*- * HVM suspend/resume support: * * Copyright (c) 2008 Citrix Systems, Inc. @@ -394,6 +361,20 @@ xctrl_on_watch_event(struct xs_watch *watch, const char **vec, unsigned int len) } /*------------------ Private Device Attachment Functions --------------------*/ + +static void +notify_support(void) +{ + /* + * Notify kernel is ready to handle "control/shutdown" events. Ignore + * errors if the nodes haven't been created by the toolstack, as the + * parent "control" directory should be read-only for the guest. + */ + xs_write(XST_NIL, "control", "feature-poweroff", "1"); + xs_write(XST_NIL, "control", "feature-reboot", "1"); + xs_write(XST_NIL, "control", "feature-suspend", "1"); +} + /** * \brief Identify instances of this device type in the system. * @@ -455,6 +436,8 @@ xctrl_attach(device_t dev) EVENTHANDLER_REGISTER(shutdown_final, xctrl_shutdown_final, NULL, SHUTDOWN_PRI_LAST); + notify_support(); + return (0); } @@ -479,6 +462,14 @@ xctrl_detach(device_t dev) return (0); } +static int +xctrl_resume(device_t dev) +{ + notify_support(); + + return (0); +} + /*-------------------- Private Device Attachment Data -----------------------*/ static device_method_t xctrl_methods[] = { /* Device interface */ @@ -486,6 +477,7 @@ static device_method_t xctrl_methods[] = { DEVMETHOD(device_probe, xctrl_probe), DEVMETHOD(device_attach, xctrl_attach), DEVMETHOD(device_detach, xctrl_detach), + DEVMETHOD(device_resume, xctrl_resume), DEVMETHOD_END }; diff --git a/sys/dev/xen/debug/debug.c b/sys/dev/xen/debug/debug.c index f17d0c612262..2889b5efdba7 100644 --- a/sys/dev/xen/debug/debug.c +++ b/sys/dev/xen/debug/debug.c @@ -58,8 +58,11 @@ static struct sbuf *buf; static int xendebug_drain(void *arg, const char *str, int len) { - - HYPERVISOR_console_write(__DECONST(char *, str), len); + /* + * Use xen_emergency_print() instead of xc_printf() to avoid the + * overhead of parsing a format string when it's not needed. + */ + xen_emergency_print(str, len); return (len); } @@ -75,10 +78,9 @@ xendebug_filter(void *arg __unused) stack_save(&st); mtx_lock_spin(&lock); - sbuf_clear(buf); xc_printf("Printing stack trace vCPU%u\n", XEN_VCPUID()); stack_sbuf_print_ddb(buf, &st); - sbuf_finish(buf); + sbuf_drain(buf); mtx_unlock_spin(&lock); #endif diff --git a/sys/dev/xen/efi/pvefi.c b/sys/dev/xen/efi/pvefi.c index f400060c1aac..b69fcd5b80ac 100644 --- a/sys/dev/xen/efi/pvefi.c +++ b/sys/dev/xen/efi/pvefi.c @@ -122,7 +122,7 @@ set_time(struct efi_tm *tm) } static int -var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib, +var_get(efi_char *name, efi_guid_t *vendor, uint32_t *attrib, size_t *datasize, void *data) { struct xen_platform_op op = { @@ -151,7 +151,7 @@ var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib, } static int -var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor) +var_nextname(size_t *namesize, efi_char *name, efi_guid_t *vendor) { struct xen_platform_op op = { .cmd = XENPF_efi_runtime_call, @@ -177,7 +177,7 @@ var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor) } static int -var_set(efi_char *name, struct uuid *vendor, uint32_t attrib, +var_set(efi_char *name, efi_guid_t *vendor, uint32_t attrib, size_t datasize, void *data) { struct xen_platform_op op = { diff --git a/sys/dev/xen/gntdev/gntdev.c b/sys/dev/xen/gntdev/gntdev.c index 4530feb1c76d..e3bc1ecf35ab 100644 --- a/sys/dev/xen/gntdev/gntdev.c +++ b/sys/dev/xen/gntdev/gntdev.c @@ -563,7 +563,6 @@ notify_unmap_cleanup(struct gntdev_gmap *gmap) { uint32_t i; int error, count; - vm_page_t m; struct gnttab_unmap_grant_ref *unmap_ops; unmap_ops = malloc(sizeof(struct gnttab_unmap_grant_ref) * gmap->count, @@ -592,17 +591,7 @@ notify_unmap_cleanup(struct gntdev_gmap *gmap) } /* Free the pages. */ - VM_OBJECT_WLOCK(gmap->map->mem); -retry: - for (i = 0; i < gmap->count; i++) { - m = vm_page_lookup(gmap->map->mem, i); - if (m == NULL) - continue; - if (vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL) == 0) - goto retry; - cdev_pager_free_page(gmap->map->mem, m); - } - VM_OBJECT_WUNLOCK(gmap->map->mem); + cdev_mgtdev_pager_free_pages(gmap->map->mem); /* Perform unmap hypercall. */ error = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index 6ac6ecc3bdb7..3bc3679eb0db 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -335,8 +335,16 @@ static void mbuf_release(struct mbuf *m) KASSERT(ref != NULL, ("Cannot find refcount")); KASSERT(ref->count > 0, ("Invalid reference count")); - if (--ref->count == 0) + if (--ref->count == 0) { + /* + * Explicitly free the tag while we hold the tx queue lock. + * This ensures that the tag is deleted promptly in case + * something else is holding extra references to the mbuf chain, + * such as netmap. + */ + m_tag_delete(m, &ref->tag); m_freem(m); + } } static void tag_free(struct m_tag *t) @@ -1021,27 +1029,6 @@ out: return (error); } -#ifdef INET -static u_int -netfront_addr_cb(void *arg, struct ifaddr *a, u_int count) -{ - arp_ifinit((if_t)arg, a); - return (1); -} -/** - * If this interface has an ipv4 address, send an arp for it. This - * helps to get the network going again after migrating hosts. - */ -static void -netfront_send_fake_arp(device_t dev, struct netfront_info *info) -{ - if_t ifp; - - ifp = info->xn_ifp; - if_foreach_addr_type(ifp, AF_INET, netfront_addr_cb, ifp); -} -#endif - /** * Callback received when the backend's state changes. */ @@ -1082,7 +1069,12 @@ netfront_backend_changed(device_t dev, XenbusState newstate) break; case XenbusStateConnected: #ifdef INET - netfront_send_fake_arp(dev, sc); + /* + * If this interface has an ipv4 address, send an arp for it. + * This helps to get the network going again after migrating + * hosts. + */ + EVENTHANDLER_INVOKE(iflladdr_event, sc->xn_ifp); #endif break; } diff --git a/sys/dev/xen/pcifront/pcifront.c b/sys/dev/xen/pcifront/pcifront.c new file mode 100644 index 000000000000..76339cd3d361 --- /dev/null +++ b/sys/dev/xen/pcifront/pcifront.c @@ -0,0 +1,690 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Cisco Systems, Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/module.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/queue.h> + +#include <machine/vmparam.h> +#include <vm/vm.h> +#include <vm/pmap.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <machine/frame.h> + +#include <sys/bus.h> +#include <sys/rman.h> + +#include <machine/intr_machdep.h> + +#include <machine/xen-os.h> +#include <machine/hypervisor.h> +#include <machine/hypervisor-ifs.h> +#include <machine/xen_intr.h> +#include <machine/evtchn.h> +#include <machine/xenbus.h> +#include <machine/gnttab.h> +#include <machine/xen-public/memory.h> +#include <machine/xen-public/io/pciif.h> + +#include <sys/pciio.h> +#include <dev/pci/pcivar.h> +#include "pcib_if.h" + +#ifdef XEN_PCIDEV_FE_DEBUG +#define DPRINTF(fmt, args...) \ + printf("pcifront (%s:%d): " fmt, __FUNCTION__, __LINE__, ##args) +#else +#define DPRINTF(fmt, args...) ((void)0) +#endif +#define WPRINTF(fmt, args...) \ + printf("pcifront (%s:%d): " fmt, __FUNCTION__, __LINE__, ##args) + +#define INVALID_GRANT_REF (0) +#define INVALID_EVTCHN (-1) +#define virt_to_mfn(x) (vtophys(x) >> PAGE_SHIFT) + +struct pcifront_device { + STAILQ_ENTRY(pcifront_device) next; + + struct xenbus_device *xdev; + + int unit; + int evtchn; + int gnt_ref; + + /* Lock this when doing any operations in sh_info */ + struct mtx sh_info_lock; + struct xen_pci_sharedinfo *sh_info; + + device_t ndev; + + int ref_cnt; +}; + +static STAILQ_HEAD(pcifront_dlist, pcifront_device) pdev_list = STAILQ_HEAD_INITIALIZER(pdev_list); + +struct xpcib_softc { + int domain; + int bus; + struct pcifront_device *pdev; +}; + +/* Allocate a PCI device structure */ +static struct pcifront_device * +alloc_pdev(struct xenbus_device *xdev) +{ + struct pcifront_device *pdev = NULL; + int err, unit; + + err = sscanf(xdev->nodename, "device/pci/%d", &unit); + if (err != 1) { + if (err == 0) + err = -EINVAL; + xenbus_dev_fatal(pdev->xdev, err, "Error scanning pci device instance number"); + goto out; + } + + pdev = (struct pcifront_device *)malloc(sizeof(struct pcifront_device), M_DEVBUF, M_NOWAIT); + if (pdev == NULL) { + err = -ENOMEM; + xenbus_dev_fatal(xdev, err, "Error allocating pcifront_device struct"); + goto out; + } + pdev->unit = unit; + pdev->xdev = xdev; + pdev->ref_cnt = 1; + + pdev->sh_info = (struct xen_pci_sharedinfo *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT); + if (pdev->sh_info == NULL) { + free(pdev, M_DEVBUF); + pdev = NULL; + err = -ENOMEM; + xenbus_dev_fatal(xdev, err, "Error allocating sh_info struct"); + goto out; + } + pdev->sh_info->flags = 0; + + xdev->data = pdev; + + mtx_init(&pdev->sh_info_lock, "info_lock", "pci shared dev info lock", MTX_DEF); + + pdev->evtchn = INVALID_EVTCHN; + pdev->gnt_ref = INVALID_GRANT_REF; + + STAILQ_INSERT_TAIL(&pdev_list, pdev, next); + + DPRINTF("Allocated pdev @ 0x%p (unit=%d)\n", pdev, unit); + + out: + return pdev; +} + +/* Hold a reference to a pcifront device */ +static void +get_pdev(struct pcifront_device *pdev) +{ + pdev->ref_cnt++; +} + +/* Release a reference to a pcifront device */ +static void +put_pdev(struct pcifront_device *pdev) +{ + if (--pdev->ref_cnt > 0) + return; + + DPRINTF("freeing pdev @ 0x%p (ref_cnt=%d)\n", pdev, pdev->ref_cnt); + + if (pdev->evtchn != INVALID_EVTCHN) + xenbus_free_evtchn(pdev->xdev, pdev->evtchn); + + if (pdev->gnt_ref != INVALID_GRANT_REF) + gnttab_end_foreign_access(pdev->gnt_ref, 0, (void *)pdev->sh_info); + + pdev->xdev->data = NULL; + + free(pdev, M_DEVBUF); +} + +/* Write to the xenbus info needed by backend */ +static int +pcifront_publish_info(struct pcifront_device *pdev) +{ + int err = 0; + struct xenbus_transaction *trans; + + err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info)); + if (err < 0) { + WPRINTF("error granting access to ring page\n"); + goto out; + } + + pdev->gnt_ref = err; + + err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn); + if (err) + goto out; + + do_publish: + trans = xenbus_transaction_start(); + if (IS_ERR(trans)) { + xenbus_dev_fatal(pdev->xdev, err, + "Error writing configuration for backend " + "(start transaction)"); + goto out; + } + + err = xenbus_printf(trans, pdev->xdev->nodename, + "pci-op-ref", "%u", pdev->gnt_ref); + if (!err) + err = xenbus_printf(trans, pdev->xdev->nodename, + "event-channel", "%u", pdev->evtchn); + if (!err) + err = xenbus_printf(trans, pdev->xdev->nodename, + "magic", XEN_PCI_MAGIC); + if (!err) + err = xenbus_switch_state(pdev->xdev, trans, + XenbusStateInitialised); + + if (err) { + xenbus_transaction_end(trans, 1); + xenbus_dev_fatal(pdev->xdev, err, + "Error writing configuration for backend"); + goto out; + } else { + err = xenbus_transaction_end(trans, 0); + if (err == -EAGAIN) + goto do_publish; + else if (err) { + xenbus_dev_fatal(pdev->xdev, err, + "Error completing transaction for backend"); + goto out; + } + } + + out: + return err; +} + +/* The backend is now connected so complete the connection process on our side */ +static int +pcifront_connect(struct pcifront_device *pdev) +{ + device_t nexus; + devclass_t nexus_devclass; + + /* We will add our device as a child of the nexus0 device */ + if (!(nexus_devclass = devclass_find("nexus")) || + !(nexus = devclass_get_device(nexus_devclass, 0))) { + WPRINTF("could not find nexus0!\n"); + return -1; + } + + /* Create a newbus device representing this frontend instance */ + pdev->ndev = BUS_ADD_CHILD(nexus, 0, "xpcife", pdev->unit); + if (!pdev->ndev) { + WPRINTF("could not create xpcife%d!\n", pdev->unit); + return -EFAULT; + } + get_pdev(pdev); + device_set_ivars(pdev->ndev, pdev); + + /* Good to go connected now */ + xenbus_switch_state(pdev->xdev, NULL, XenbusStateConnected); + + printf("pcifront: connected to %s\n", pdev->xdev->nodename); + + mtx_lock(&Giant); + device_probe_and_attach(pdev->ndev); + mtx_unlock(&Giant); + + return 0; +} + +/* The backend is closing so process a disconnect */ +static int +pcifront_disconnect(struct pcifront_device *pdev) +{ + int err = 0; + XenbusState prev_state; + + prev_state = xenbus_read_driver_state(pdev->xdev->nodename); + + if (prev_state < XenbusStateClosing) { + err = xenbus_switch_state(pdev->xdev, NULL, XenbusStateClosing); + if (!err && prev_state == XenbusStateConnected) { + /* TODO - need to detach the newbus devices */ + } + } + + return err; +} + +/* Process a probe from the xenbus */ +static int +pcifront_probe(struct xenbus_device *xdev, + const struct xenbus_device_id *id) +{ + int err = 0; + struct pcifront_device *pdev; + + DPRINTF("xenbus probing\n"); + + if ((pdev = alloc_pdev(xdev)) == NULL) + goto out; + + err = pcifront_publish_info(pdev); + + out: + if (err) + put_pdev(pdev); + return err; +} + +/* Remove the xenbus PCI device */ +static int +pcifront_remove(struct xenbus_device *xdev) +{ + DPRINTF("removing xenbus device node (%s)\n", xdev->nodename); + if (xdev->data) + put_pdev(xdev->data); + return 0; +} + +/* Called by xenbus when our backend node changes state */ +static void +pcifront_backend_changed(struct xenbus_device *xdev, + XenbusState be_state) +{ + struct pcifront_device *pdev = xdev->data; + + switch (be_state) { + case XenbusStateClosing: + DPRINTF("backend closing (%s)\n", xdev->nodename); + pcifront_disconnect(pdev); + break; + + case XenbusStateClosed: + DPRINTF("backend closed (%s)\n", xdev->nodename); + pcifront_disconnect(pdev); + break; + + case XenbusStateConnected: + DPRINTF("backend connected (%s)\n", xdev->nodename); + pcifront_connect(pdev); + break; + + default: + break; + } +} + +/* Process PCI operation */ +static int +do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op) +{ + int err = 0; + struct xen_pci_op *active_op = &pdev->sh_info->op; + evtchn_port_t port = pdev->evtchn; + time_t timeout; + + mtx_lock(&pdev->sh_info_lock); + + memcpy(active_op, op, sizeof(struct xen_pci_op)); + + /* Go */ + wmb(); + set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags); + notify_remote_via_evtchn(port); + + timeout = time_uptime + 2; + + clear_evtchn(port); + + /* Spin while waiting for the answer */ + while (test_bit + (_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags)) { + int err = HYPERVISOR_poll(&port, 1, 3 * hz); + if (err) + panic("Failed HYPERVISOR_poll: err=%d", err); + clear_evtchn(port); + if (time_uptime > timeout) { + WPRINTF("pciback not responding!!!\n"); + clear_bit(_XEN_PCIF_active, + (unsigned long *)&pdev->sh_info->flags); + err = XEN_PCI_ERR_dev_not_found; + goto out; + } + } + + memcpy(op, active_op, sizeof(struct xen_pci_op)); + + err = op->err; + out: + mtx_unlock(&pdev->sh_info_lock); + return err; +} + +/* ** XenBus Driver registration ** */ + +static struct xenbus_device_id pcifront_ids[] = { + { "pci" }, + { "" } +}; + +static struct xenbus_driver pcifront = { + .name = "pcifront", + .ids = pcifront_ids, + .probe = pcifront_probe, + .remove = pcifront_remove, + .otherend_changed = pcifront_backend_changed, +}; + +/* Register the driver with xenbus during sys init */ +static void +pcifront_init(void *unused) +{ + if ((xen_start_info->flags & SIF_INITDOMAIN)) + return; + + DPRINTF("xenbus registering\n"); + + xenbus_register_frontend(&pcifront); +} + +SYSINIT(pciif, SI_SUB_PSEUDO, SI_ORDER_ANY, pcifront_init, NULL) + +/* Newbus xpcife device driver probe */ +static int +xpcife_probe(device_t dev) +{ +#ifdef XEN_PCIDEV_FE_DEBUG + struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(dev); + DPRINTF("xpcife probe (unit=%d)\n", pdev->unit); +#endif + return (BUS_PROBE_NOWILDCARD); +} + +/* Newbus xpcife device driver attach */ +static int +xpcife_attach(device_t dev) +{ + struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(dev); + int i, num_roots, len, err; + char str[64]; + unsigned int domain, bus; + + DPRINTF("xpcife attach (unit=%d)\n", pdev->unit); + + err = xenbus_scanf(NULL, pdev->xdev->otherend, + "root_num", "%d", &num_roots); + if (err != 1) { + if (err == 0) + err = -EINVAL; + xenbus_dev_fatal(pdev->xdev, err, + "Error reading number of PCI roots"); + goto out; + } + + /* Add a pcib device for each root */ + for (i = 0; i < num_roots; i++) { + device_t child; + + len = snprintf(str, sizeof(str), "root-%d", i); + if (unlikely(len >= (sizeof(str) - 1))) { + err = -ENOMEM; + goto out; + } + + err = xenbus_scanf(NULL, pdev->xdev->otherend, str, + "%x:%x", &domain, &bus); + if (err != 2) { + if (err >= 0) + err = -EINVAL; + xenbus_dev_fatal(pdev->xdev, err, + "Error reading PCI root %d", i); + goto out; + } + err = 0; + if (domain != pdev->xdev->otherend_id) { + err = -EINVAL; + xenbus_dev_fatal(pdev->xdev, err, + "Domain mismatch %d != %d", domain, pdev->xdev->otherend_id); + goto out; + } + + child = device_add_child(dev, "pcib", bus); + if (!child) { + err = -ENOMEM; + xenbus_dev_fatal(pdev->xdev, err, + "Unable to create pcib%d", bus); + goto out; + } + } + + out: + bus_attach_children(dev); + return (0); +} + +static devclass_t xpcife_devclass; + +static device_method_t xpcife_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, xpcife_probe), + DEVMETHOD(device_attach, xpcife_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + /* Bus interface */ + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + DEVMETHOD_END +}; + +static driver_t xpcife_driver = { + "xpcife", + xpcife_methods, + 0, +}; + +DRIVER_MODULE(xpcife, nexus, xpcife_driver, xpcife_devclass, 0, 0); + +/* Newbus xen pcib device driver probe */ +static int +xpcib_probe(device_t dev) +{ + struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); + struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(device_get_parent(dev)); + + DPRINTF("xpcib probe (bus=%d)\n", device_get_unit(dev)); + + sc->domain = pdev->xdev->otherend_id; + sc->bus = device_get_unit(dev); + sc->pdev = pdev; + + return 0; +} + +/* Newbus xen pcib device driver attach */ +static int +xpcib_attach(device_t dev) +{ + struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); + + DPRINTF("xpcib attach (bus=%d)\n", sc->bus); + + device_add_child(dev, "pci", DEVICE_UNIT_ANY); + bus_attach_children(dev); + return (0); +} + +static int +xpcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) +{ + struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); + switch (which) { + case PCIB_IVAR_BUS: + *result = sc->bus; + return 0; + } + return ENOENT; +} + +/* Return the number of slots supported */ +static int +xpcib_maxslots(device_t dev) +{ + return 31; +} + +#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) + +/* Read configuration space register */ +static u_int32_t +xpcib_read_config(device_t dev, int bus, int slot, int func, + int reg, int bytes) +{ + struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); + struct xen_pci_op op = { + .cmd = XEN_PCI_OP_conf_read, + .domain = sc->domain, + .bus = sc->bus, + .devfn = PCI_DEVFN(slot, func), + .offset = reg, + .size = bytes, + }; + int err; + + err = do_pci_op(sc->pdev, &op); + + DPRINTF("read config (b=%d, s=%d, f=%d, reg=%d, len=%d, val=%x, err=%d)\n", + bus, slot, func, reg, bytes, op.value, err); + + if (err) + op.value = ~0; + + return op.value; +} + +/* Write configuration space register */ +static void +xpcib_write_config(device_t dev, int bus, int slot, int func, + int reg, u_int32_t data, int bytes) +{ + struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); + struct xen_pci_op op = { + .cmd = XEN_PCI_OP_conf_write, + .domain = sc->domain, + .bus = sc->bus, + .devfn = PCI_DEVFN(slot, func), + .offset = reg, + .size = bytes, + .value = data, + }; + int err; + + err = do_pci_op(sc->pdev, &op); + + DPRINTF("write config (b=%d, s=%d, f=%d, reg=%d, len=%d, val=%x, err=%d)\n", + bus, slot, func, reg, bytes, data, err); +} + +static int +xpcib_route_interrupt(device_t pcib, device_t dev, int pin) +{ + struct pci_devinfo *dinfo = device_get_ivars(dev); + pcicfgregs *cfg = &dinfo->cfg; + + DPRINTF("route intr (pin=%d, line=%d)\n", pin, cfg->intline); + + return cfg->intline; +} + +static device_method_t xpcib_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, xpcib_probe), + DEVMETHOD(device_attach, xpcib_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_read_ivar, xpcib_read_ivar), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + /* pcib interface */ + DEVMETHOD(pcib_maxslots, xpcib_maxslots), + DEVMETHOD(pcib_read_config, xpcib_read_config), + DEVMETHOD(pcib_write_config, xpcib_write_config), + DEVMETHOD(pcib_route_interrupt, xpcib_route_interrupt), + DEVMETHOD(pcib_request_feature, pcib_request_feature_allow), + + DEVMETHOD_END +}; + +static devclass_t xpcib_devclass; + +DEFINE_CLASS_0(pcib, xpcib_driver, xpcib_methods, sizeof(struct xpcib_softc)); +DRIVER_MODULE(pcib, xpcife, xpcib_driver, xpcib_devclass, 0, 0); + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: t + * End: + */ diff --git a/sys/dev/xen/privcmd/privcmd.c b/sys/dev/xen/privcmd/privcmd.c index 02e268b23d42..922d24b39432 100644 --- a/sys/dev/xen/privcmd/privcmd.c +++ b/sys/dev/xen/privcmd/privcmd.c @@ -120,25 +120,13 @@ privcmd_pg_dtor(void *handle) struct privcmd_map *map = handle; int error __diagused; vm_size_t i; - vm_page_t m; /* * Remove the mappings from the used pages. This will remove the * underlying p2m bindings in Xen second stage translation. */ if (map->mapped == true) { - VM_OBJECT_WLOCK(map->mem); -retry: - for (i = 0; i < map->size; i++) { - m = vm_page_lookup(map->mem, i); - if (m == NULL) - continue; - if (vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL) == 0) - goto retry; - cdev_pager_free_page(map->mem, m); - } - VM_OBJECT_WUNLOCK(map->mem); - + cdev_mgtdev_pager_free_pages(map->mem); for (i = 0; i < map->size; i++) { rm.gpfn = atop(map->phys_base_addr) + i; HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &rm); diff --git a/sys/dev/xen/xenpci/xenpci.c b/sys/dev/xen/xenpci/xenpci.c index b7a810bf9e15..f4cbd927bd63 100644 --- a/sys/dev/xen/xenpci/xenpci.c +++ b/sys/dev/xen/xenpci/xenpci.c @@ -31,13 +31,12 @@ #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/module.h> +#include <sys/stdarg.h> #include <machine/bus.h> #include <machine/resource.h> #include <sys/rman.h> -#include <machine/stdarg.h> - #include <xen/xen-os.h> #include <xen/features.h> #include <xen/hypervisor.h> @@ -127,8 +126,9 @@ errexit: static int xenpci_probe(device_t dev) { + uint32_t device_id = pci_get_devid(dev); - if (pci_get_devid(dev) != 0x00015853) + if (device_id != 0x00015853 && device_id != 0x00025853) return (ENXIO); device_set_desc(dev, "Xen Platform Device"); diff --git a/sys/dev/xen/xenstore/xenstore.c b/sys/dev/xen/xenstore/xenstore.c index 811aa1859d41..e5187466f1fe 100644 --- a/sys/dev/xen/xenstore/xenstore.c +++ b/sys/dev/xen/xenstore/xenstore.c @@ -45,10 +45,9 @@ #include <sys/uio.h> #include <sys/unistd.h> #include <sys/queue.h> +#include <sys/stdarg.h> #include <sys/taskqueue.h> -#include <machine/stdarg.h> - #include <xen/xen-os.h> #include <xen/hypervisor.h> #include <xen/xen_intr.h> @@ -1068,8 +1067,8 @@ static void xs_attach_deferred(void *arg) { - bus_generic_probe(xs.xs_dev); - bus_generic_attach(xs.xs_dev); + bus_identify_children(xs.xs_dev); + bus_attach_children(xs.xs_dev); config_intrhook_disestablish(&xs.xs_attachcb); } @@ -1079,8 +1078,8 @@ xs_attach_late(void *arg, int pending) { KASSERT((pending == 1), ("xs late attach queued several times")); - bus_generic_probe(xs.xs_dev); - bus_generic_attach(xs.xs_dev); + bus_identify_children(xs.xs_dev); + bus_attach_children(xs.xs_dev); } /** |