diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-07-01 13:03:51 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-07-01 13:03:51 +0100 |
commit | ab67678a59e31d30b0f8587cdc245f93c2e56fef (patch) | |
tree | ebf1089bdc110370e7f976b283ea2e61bb7039b1 /hw | |
parent | 7fec76a02267598a4e437ddfdaeaeb6de09b92f3 (diff) | |
parent | a3434a2d56aee3018f4a0f55c7e0f0cda11f3d9e (diff) | |
download | qemu-ab67678a59e31d30b0f8587cdc245f93c2e56fef.zip qemu-ab67678a59e31d30b0f8587cdc245f93c2e56fef.tar.gz qemu-ab67678a59e31d30b0f8587cdc245f93c2e56fef.tar.bz2 |
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20190624' into staging
Xen queue
* Fix build
* xen-block: support feature-large-sector-size
* xen-block: Support IOThread polling for PV shared rings
* Avoid usage of a VLA
* Cleanup Xen headers usage
# gpg: Signature made Mon 24 Jun 2019 16:30:32 BST
# gpg: using RSA key F80C006308E22CFD8A92E7980CF5572FD7FB55AF
# gpg: issuer "anthony.perard@citrix.com"
# gpg: Good signature from "Anthony PERARD <anthony.perard@gmail.com>" [marginal]
# gpg: aka "Anthony PERARD <anthony.perard@citrix.com>" [marginal]
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg: It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 5379 2F71 024C 600F 778A 7161 D8D5 7199 DF83 42C8
# Subkey fingerprint: F80C 0063 08E2 2CFD 8A92 E798 0CF5 572F D7FB 55AF
* remotes/aperard/tags/pull-xen-20190624:
xen: Import other xen/io/*.h
Revert xen/io/ring.h of "Clean up a few header guard symbols"
xen: Drop includes of xen/hvm/params.h
xen: Avoid VLA
xen-bus / xen-block: add support for event channel polling
xen-bus: allow AioContext to be specified for each event channel
xen-bus: use a separate fd for each event channel
xen-block: support feature-large-sector-size
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/9pfs/xen-9pfs.h | 4 | ||||
-rw-r--r-- | hw/block/dataplane/xen-block.c | 44 | ||||
-rw-r--r-- | hw/block/dataplane/xen-block.h | 3 | ||||
-rw-r--r-- | hw/block/xen-block.c | 38 | ||||
-rw-r--r-- | hw/block/xen_blkif.h | 5 | ||||
-rw-r--r-- | hw/char/xen_console.c | 2 | ||||
-rw-r--r-- | hw/display/xenfb.c | 7 | ||||
-rw-r--r-- | hw/i386/xen/xen-hvm.c | 16 | ||||
-rw-r--r-- | hw/i386/xen/xen-mapcache.c | 2 | ||||
-rw-r--r-- | hw/net/xen_nic.c | 2 | ||||
-rw-r--r-- | hw/usb/xen-usb.c | 3 | ||||
-rw-r--r-- | hw/xen/xen-bus.c | 92 | ||||
-rw-r--r-- | hw/xen/xen-legacy-backend.c | 2 |
13 files changed, 123 insertions, 97 deletions
diff --git a/hw/9pfs/xen-9pfs.h b/hw/9pfs/xen-9pfs.h index fbdee3d..241e221 100644 --- a/hw/9pfs/xen-9pfs.h +++ b/hw/9pfs/xen-9pfs.h @@ -13,8 +13,8 @@ #ifndef HW_9PFS_XEN_9PFS_H #define HW_9PFS_XEN_9PFS_H -#include <xen/io/protocols.h> -#include "hw/xen/io/ring.h" +#include "hw/xen/interface/io/protocols.h" +#include "hw/xen/interface/io/ring.h" /* * Do not merge into xen-9p-backend.c: clang doesn't allow unused static diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index f7ad452..0f200c5 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -58,6 +58,7 @@ struct XenBlockDataPlane { int requests_inflight; unsigned int max_requests; BlockBackend *blk; + unsigned int sector_size; QEMUBH *bh; IOThread *iothread; AioContext *ctx; @@ -167,7 +168,7 @@ static int xen_block_parse_request(XenBlockRequest *request) goto err; } - request->start = request->req.sector_number * XEN_BLKIF_SECTOR_SIZE; + request->start = request->req.sector_number * dataplane->sector_size; for (i = 0; i < request->req.nr_segments; i++) { if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) { error_report("error: nr_segments too big"); @@ -177,14 +178,14 @@ static int xen_block_parse_request(XenBlockRequest *request) error_report("error: first > last sector"); goto err; } - if (request->req.seg[i].last_sect * XEN_BLKIF_SECTOR_SIZE >= + if (request->req.seg[i].last_sect * dataplane->sector_size >= XC_PAGE_SIZE) { error_report("error: page crossing"); goto err; } len = (request->req.seg[i].last_sect - - request->req.seg[i].first_sect + 1) * XEN_BLKIF_SECTOR_SIZE; + request->req.seg[i].first_sect + 1) * dataplane->sector_size; request->size += len; } if (request->start + request->size > blk_getlength(dataplane->blk)) { @@ -218,17 +219,17 @@ static int xen_block_copy_request(XenBlockRequest *request) if (to_domain) { segs[i].dest.foreign.ref = request->req.seg[i].gref; segs[i].dest.foreign.offset = request->req.seg[i].first_sect * - XEN_BLKIF_SECTOR_SIZE; + dataplane->sector_size; segs[i].source.virt = virt; } else { segs[i].source.foreign.ref = request->req.seg[i].gref; segs[i].source.foreign.offset = request->req.seg[i].first_sect * - XEN_BLKIF_SECTOR_SIZE; + dataplane->sector_size; segs[i].dest.virt = virt; } segs[i].len = (request->req.seg[i].last_sect - request->req.seg[i].first_sect + 1) * - XEN_BLKIF_SECTOR_SIZE; + dataplane->sector_size; virt += segs[i].len; } @@ -317,7 +318,9 @@ static void xen_block_complete_aio(void *opaque, int ret) } xen_block_release_request(request); - qemu_bh_schedule(dataplane->bh); + if (dataplane->more_work) { + qemu_bh_schedule(dataplane->bh); + } done: aio_context_release(dataplane->ctx); @@ -336,12 +339,12 @@ static bool xen_block_split_discard(XenBlockRequest *request, /* Wrap around, or overflowing byte limit? */ if (sec_start + sec_count < sec_count || - sec_start + sec_count > INT64_MAX / XEN_BLKIF_SECTOR_SIZE) { + sec_start + sec_count > INT64_MAX / dataplane->sector_size) { return false; } - byte_offset = sec_start * XEN_BLKIF_SECTOR_SIZE; - byte_remaining = sec_count * XEN_BLKIF_SECTOR_SIZE; + byte_offset = sec_start * dataplane->sector_size; + byte_remaining = sec_count * dataplane->sector_size; do { byte_chunk = byte_remaining > BDRV_REQUEST_MAX_BYTES ? @@ -514,12 +517,13 @@ static int xen_block_get_request(XenBlockDataPlane *dataplane, */ #define IO_PLUG_THRESHOLD 1 -static void xen_block_handle_requests(XenBlockDataPlane *dataplane) +static bool xen_block_handle_requests(XenBlockDataPlane *dataplane) { RING_IDX rc, rp; XenBlockRequest *request; int inflight_atstart = dataplane->requests_inflight; int batched = 0; + bool done_something = false; dataplane->more_work = 0; @@ -551,6 +555,7 @@ static void xen_block_handle_requests(XenBlockDataPlane *dataplane) } xen_block_get_request(dataplane, request, rc); dataplane->rings.common.req_cons = ++rc; + done_something = true; /* parse them */ if (xen_block_parse_request(request) != 0) { @@ -602,10 +607,7 @@ static void xen_block_handle_requests(XenBlockDataPlane *dataplane) blk_io_unplug(dataplane->blk); } - if (dataplane->more_work && - dataplane->requests_inflight < dataplane->max_requests) { - qemu_bh_schedule(dataplane->bh); - } + return done_something; } static void xen_block_dataplane_bh(void *opaque) @@ -617,21 +619,23 @@ static void xen_block_dataplane_bh(void *opaque) aio_context_release(dataplane->ctx); } -static void xen_block_dataplane_event(void *opaque) +static bool xen_block_dataplane_event(void *opaque) { XenBlockDataPlane *dataplane = opaque; - qemu_bh_schedule(dataplane->bh); + return xen_block_handle_requests(dataplane); } XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, - BlockConf *conf, + BlockBackend *blk, + unsigned int sector_size, IOThread *iothread) { XenBlockDataPlane *dataplane = g_new0(XenBlockDataPlane, 1); dataplane->xendev = xendev; - dataplane->blk = conf->blk; + dataplane->blk = blk; + dataplane->sector_size = sector_size; QLIST_INIT(&dataplane->inflight); QLIST_INIT(&dataplane->freelist); @@ -803,7 +807,7 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, } dataplane->event_channel = - xen_device_bind_event_channel(xendev, event_channel, + xen_device_bind_event_channel(xendev, dataplane->ctx, event_channel, xen_block_dataplane_event, dataplane, &local_err); if (local_err) { diff --git a/hw/block/dataplane/xen-block.h b/hw/block/dataplane/xen-block.h index d6fa6d2..76dcd51 100644 --- a/hw/block/dataplane/xen-block.h +++ b/hw/block/dataplane/xen-block.h @@ -15,7 +15,8 @@ typedef struct XenBlockDataPlane XenBlockDataPlane; XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, - BlockConf *conf, + BlockBackend *blk, + unsigned int sector_size, IOThread *iothread); void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane); void xen_block_dataplane_start(XenBlockDataPlane *dataplane, diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index 4de537a..8f224ef 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -52,11 +52,25 @@ static void xen_block_connect(XenDevice *xendev, Error **errp) XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev); const char *type = object_get_typename(OBJECT(blockdev)); XenBlockVdev *vdev = &blockdev->props.vdev; + BlockConf *conf = &blockdev->props.conf; + unsigned int feature_large_sector_size; unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol; char *str; trace_xen_block_connect(type, vdev->disk, vdev->partition); + if (xen_device_frontend_scanf(xendev, "feature-large-sector-size", "%u", + &feature_large_sector_size) != 1) { + feature_large_sector_size = 0; + } + + if (feature_large_sector_size != 1 && + conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) { + error_setg(errp, "logical_block_size != %u not supported by frontend", + XEN_BLKIF_SECTOR_SIZE); + return; + } + if (xen_device_frontend_scanf(xendev, "ring-page-order", "%u", &order) != 1) { nr_ring_ref = 1; @@ -150,7 +164,7 @@ static void xen_block_set_size(XenBlockDevice *blockdev) const char *type = object_get_typename(OBJECT(blockdev)); XenBlockVdev *vdev = &blockdev->props.vdev; BlockConf *conf = &blockdev->props.conf; - int64_t sectors = blk_getlength(conf->blk) / XEN_BLKIF_SECTOR_SIZE; + int64_t sectors = blk_getlength(conf->blk) / conf->logical_block_size; XenDevice *xendev = XEN_DEVICE(blockdev); trace_xen_block_size(type, vdev->disk, vdev->partition, sectors); @@ -185,6 +199,7 @@ static void xen_block_realize(XenDevice *xendev, Error **errp) const char *type = object_get_typename(OBJECT(blockdev)); XenBlockVdev *vdev = &blockdev->props.vdev; BlockConf *conf = &blockdev->props.conf; + BlockBackend *blk = conf->blk; Error *local_err = NULL; if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) { @@ -206,8 +221,8 @@ static void xen_block_realize(XenDevice *xendev, Error **errp) * The blkif protocol does not deal with removable media, so it must * always be present, even for CDRom devices. */ - assert(conf->blk); - if (!blk_is_inserted(conf->blk)) { + assert(blk); + if (!blk_is_inserted(blk)) { error_setg(errp, "device needs media, but drive is empty"); return; } @@ -224,26 +239,20 @@ static void xen_block_realize(XenDevice *xendev, Error **errp) blkconf_blocksizes(conf); - if (conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) { - error_setg(errp, "logical_block_size != %u not supported", - XEN_BLKIF_SECTOR_SIZE); - return; - } - if (conf->logical_block_size > conf->physical_block_size) { error_setg( errp, "logical_block_size > physical_block_size not supported"); return; } - blk_set_dev_ops(conf->blk, &xen_block_dev_ops, blockdev); - blk_set_guest_block_size(conf->blk, conf->logical_block_size); + blk_set_dev_ops(blk, &xen_block_dev_ops, blockdev); + blk_set_guest_block_size(blk, conf->logical_block_size); if (conf->discard_granularity == -1) { conf->discard_granularity = conf->physical_block_size; } - if (blk_get_flags(conf->blk) & BDRV_O_UNMAP) { + if (blk_get_flags(blk) & BDRV_O_UNMAP) { xen_device_backend_printf(xendev, "feature-discard", "%u", 1); xen_device_backend_printf(xendev, "discard-granularity", "%u", conf->discard_granularity); @@ -260,12 +269,13 @@ static void xen_block_realize(XenDevice *xendev, Error **errp) blockdev->device_type); xen_device_backend_printf(xendev, "sector-size", "%u", - XEN_BLKIF_SECTOR_SIZE); + conf->logical_block_size); xen_block_set_size(blockdev); blockdev->dataplane = - xen_block_dataplane_create(xendev, conf, blockdev->props.iothread); + xen_block_dataplane_create(xendev, blk, conf->logical_block_size, + blockdev->props.iothread); } static void xen_block_frontend_changed(XenDevice *xendev, diff --git a/hw/block/xen_blkif.h b/hw/block/xen_blkif.h index a353693..9973352 100644 --- a/hw/block/xen_blkif.h +++ b/hw/block/xen_blkif.h @@ -1,9 +1,8 @@ #ifndef XEN_BLKIF_H #define XEN_BLKIF_H -#include "hw/xen/io/ring.h" -#include <xen/io/blkif.h> -#include <xen/io/protocols.h> +#include "hw/xen/interface/io/blkif.h" +#include "hw/xen/interface/io/protocols.h" /* * Not a real protocol. Used to generate ring structs which contain diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index 91f34ef..47e1092 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -28,7 +28,7 @@ #include "chardev/char-fe.h" #include "hw/xen/xen-legacy-backend.h" -#include <xen/io/console.h> +#include "hw/xen/interface/io/console.h" struct buffer { uint8_t *data; diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 6202f11..3c79913 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -32,10 +32,9 @@ #include "ui/console.h" #include "hw/xen/xen-legacy-backend.h" -#include <xen/event_channel.h> -#include <xen/io/fbif.h> -#include <xen/io/kbdif.h> -#include <xen/io/protocols.h> +#include "hw/xen/interface/io/fbif.h" +#include "hw/xen/interface/io/kbdif.h" +#include "hw/xen/interface/io/protocols.h" #include "trace.h" diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index 2939122..469f126 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -27,7 +27,6 @@ #include "exec/address-spaces.h" #include <xen/hvm/ioreq.h> -#include <xen/hvm/params.h> #include <xen/hvm/e820.h> //#define DEBUG_XEN_HVM @@ -120,6 +119,8 @@ typedef struct XenIOState { DeviceListener device_listener; hwaddr free_phys_offset; const XenPhysmap *log_for_dirtybit; + /* Buffer used by xen_sync_dirty_bitmap */ + unsigned long *dirty_bitmap; Notifier exit; Notifier suspend; @@ -465,6 +466,8 @@ static int xen_remove_from_physmap(XenIOState *state, QLIST_REMOVE(physmap, list); if (state->log_for_dirtybit == physmap) { state->log_for_dirtybit = NULL; + g_free(state->dirty_bitmap); + state->dirty_bitmap = NULL; } g_free(physmap); @@ -615,7 +618,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state, { hwaddr npages = size >> TARGET_PAGE_BITS; const int width = sizeof(unsigned long) * 8; - unsigned long bitmap[DIV_ROUND_UP(npages, width)]; + size_t bitmap_size = DIV_ROUND_UP(npages, width); int rc, i, j; const XenPhysmap *physmap = NULL; @@ -627,13 +630,14 @@ static void xen_sync_dirty_bitmap(XenIOState *state, if (state->log_for_dirtybit == NULL) { state->log_for_dirtybit = physmap; + state->dirty_bitmap = g_new(unsigned long, bitmap_size); } else if (state->log_for_dirtybit != physmap) { /* Only one range for dirty bitmap can be tracked. */ return; } rc = xen_track_dirty_vram(xen_domid, start_addr >> TARGET_PAGE_BITS, - npages, bitmap); + npages, state->dirty_bitmap); if (rc < 0) { #ifndef ENODATA #define ENODATA ENOENT @@ -647,8 +651,8 @@ static void xen_sync_dirty_bitmap(XenIOState *state, return; } - for (i = 0; i < ARRAY_SIZE(bitmap); i++) { - unsigned long map = bitmap[i]; + for (i = 0; i < bitmap_size; i++) { + unsigned long map = state->dirty_bitmap[i]; while (map != 0) { j = ctzl(map); map &= ~(1ul << j); @@ -678,6 +682,8 @@ static void xen_log_stop(MemoryListener *listener, MemoryRegionSection *section, if (old & ~new & (1 << DIRTY_MEMORY_VGA)) { state->log_for_dirtybit = NULL; + g_free(state->dirty_bitmap); + state->dirty_bitmap = NULL; /* Disable dirty bit tracking */ xen_track_dirty_vram(xen_domid, 0, 0, NULL); } diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c index 254759f..dc73c86 100644 --- a/hw/i386/xen/xen-mapcache.c +++ b/hw/i386/xen/xen-mapcache.c @@ -17,8 +17,6 @@ #include "hw/xen/xen-legacy-backend.h" #include "qemu/bitmap.h" -#include <xen/hvm/params.h> - #include "sysemu/xen-mapcache.h" #include "trace.h" diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 37cda8e..ffb3b58 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -30,7 +30,7 @@ #include "net/util.h" #include "hw/xen/xen-legacy-backend.h" -#include <xen/io/netif.h> +#include "hw/xen/interface/io/netif.h" /* ------------------------------------------------------------- */ diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c index b20d0cf..dfbb418 100644 --- a/hw/usb/xen-usb.c +++ b/hw/usb/xen-usb.c @@ -32,8 +32,7 @@ #include "qapi/qmp/qdict.h" #include "qapi/qmp/qstring.h" -#include "hw/xen/io/ring.h" -#include <xen/io/usbif.h> +#include "hw/xen/interface/io/usbif.h" /* * Check for required support of usbif.h: USBIF_SHORT_NOT_OK was the last diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index a4416d0..7503eea 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -924,23 +924,35 @@ done: } struct XenEventChannel { + QLIST_ENTRY(XenEventChannel) list; + AioContext *ctx; + xenevtchn_handle *xeh; evtchn_port_t local_port; XenEventHandler handler; void *opaque; - Notifier notifier; }; -static void event_notify(Notifier *n, void *data) +static bool xen_device_poll(void *opaque) +{ + XenEventChannel *channel = opaque; + + return channel->handler(channel->opaque); +} + +static void xen_device_event(void *opaque) { - XenEventChannel *channel = container_of(n, XenEventChannel, notifier); - unsigned long port = (unsigned long)data; + XenEventChannel *channel = opaque; + unsigned long port = xenevtchn_pending(channel->xeh); if (port == channel->local_port) { - channel->handler(channel->opaque); + xen_device_poll(channel); + + xenevtchn_unmask(channel->xeh, port); } } XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, + AioContext *ctx, unsigned int port, XenEventHandler handler, void *opaque, Error **errp) @@ -948,24 +960,40 @@ XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, XenEventChannel *channel = g_new0(XenEventChannel, 1); xenevtchn_port_or_error_t local_port; - local_port = xenevtchn_bind_interdomain(xendev->xeh, + channel->xeh = xenevtchn_open(NULL, 0); + if (!channel->xeh) { + error_setg_errno(errp, errno, "failed xenevtchn_open"); + goto fail; + } + + local_port = xenevtchn_bind_interdomain(channel->xeh, xendev->frontend_id, port); if (local_port < 0) { error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed"); - - g_free(channel); - return NULL; + goto fail; } channel->local_port = local_port; channel->handler = handler; channel->opaque = opaque; - channel->notifier.notify = event_notify; - notifier_list_add(&xendev->event_notifiers, &channel->notifier); + channel->ctx = ctx; + aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, + xen_device_event, NULL, xen_device_poll, channel); + + QLIST_INSERT_HEAD(&xendev->event_channels, channel, list); return channel; + +fail: + if (channel->xeh) { + xenevtchn_close(channel->xeh); + } + + g_free(channel); + + return NULL; } void xen_device_notify_event_channel(XenDevice *xendev, @@ -977,7 +1005,7 @@ void xen_device_notify_event_channel(XenDevice *xendev, return; } - if (xenevtchn_notify(xendev->xeh, channel->local_port) < 0) { + if (xenevtchn_notify(channel->xeh, channel->local_port) < 0) { error_setg_errno(errp, errno, "xenevtchn_notify failed"); } } @@ -991,12 +1019,16 @@ void xen_device_unbind_event_channel(XenDevice *xendev, return; } - notifier_remove(&channel->notifier); + QLIST_REMOVE(channel, list); + + aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, + NULL, NULL, NULL, NULL); - if (xenevtchn_unbind(xendev->xeh, channel->local_port) < 0) { + if (xenevtchn_unbind(channel->xeh, channel->local_port) < 0) { error_setg_errno(errp, errno, "xenevtchn_unbind failed"); } + xenevtchn_close(channel->xeh); g_free(channel); } @@ -1005,6 +1037,7 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp) XenDevice *xendev = XEN_DEVICE(dev); XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); const char *type = object_get_typename(OBJECT(xendev)); + XenEventChannel *channel, *next; if (!xendev->name) { return; @@ -1021,15 +1054,14 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp) xendev_class->unrealize(xendev, errp); } + /* Make sure all event channels are cleaned up */ + QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) { + xen_device_unbind_event_channel(xendev, channel, NULL); + } + xen_device_frontend_destroy(xendev); xen_device_backend_destroy(xendev); - if (xendev->xeh) { - qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), NULL, NULL, NULL); - xenevtchn_close(xendev->xeh); - xendev->xeh = NULL; - } - if (xendev->xgth) { xengnttab_close(xendev->xgth); xendev->xgth = NULL; @@ -1046,16 +1078,6 @@ static void xen_device_exit(Notifier *n, void *data) xen_device_unrealize(DEVICE(xendev), &error_abort); } -static void xen_device_event(void *opaque) -{ - XenDevice *xendev = opaque; - unsigned long port = xenevtchn_pending(xendev->xeh); - - notifier_list_notify(&xendev->event_notifiers, (void *)port); - - xenevtchn_unmask(xendev->xeh, port); -} - static void xen_device_realize(DeviceState *dev, Error **errp) { XenDevice *xendev = XEN_DEVICE(dev); @@ -1096,16 +1118,6 @@ static void xen_device_realize(DeviceState *dev, Error **errp) xendev->feature_grant_copy = (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0); - xendev->xeh = xenevtchn_open(NULL, 0); - if (!xendev->xeh) { - error_setg_errno(errp, errno, "failed xenevtchn_open"); - goto unrealize; - } - - notifier_list_init(&xendev->event_notifiers); - qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), xen_device_event, NULL, - xendev); - xen_device_backend_create(xendev, &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c index 36fd1e9..3715c94 100644 --- a/hw/xen/xen-legacy-backend.c +++ b/hw/xen/xen-legacy-backend.c @@ -34,8 +34,6 @@ #include "hw/xen/xen_pvdev.h" #include "monitor/qdev.h" -#include <xen/grant_table.h> - DeviceState *xen_sysdev; BusState *xen_sysbus; |