/*
 * QEMU Hyper-V VMBus
 *
 * Copyright (c) 2017-2018 Virtuozzo International GmbH.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qapi/error.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "hw/hyperv/hyperv.h"
#include "hw/hyperv/vmbus.h"
#include "hw/hyperv/vmbus-bridge.h"
#include "hw/sysbus.h"
#include "cpu.h"
#include "trace.h"

enum {
    VMGPADL_INIT,
    VMGPADL_ALIVE,
    VMGPADL_TEARINGDOWN,
    VMGPADL_TORNDOWN,
};

struct VMBusGpadl {
    /* GPADL id */
    uint32_t id;
    /* associated channel id (rudimentary?) */
    uint32_t child_relid;

    /* number of pages in the GPADL as declared in GPADL_HEADER message */
    uint32_t num_gfns;
    /*
     * Due to limited message size, GPADL may not fit fully in a single
     * GPADL_HEADER message, and is further popluated using GPADL_BODY
     * messages.  @seen_gfns is the number of pages seen so far; once it
     * reaches @num_gfns, the GPADL is ready to use.
     */
    uint32_t seen_gfns;
    /* array of GFNs (of size @num_gfns once allocated) */
    uint64_t *gfns;

    uint8_t state;

    QTAILQ_ENTRY(VMBusGpadl) link;
    VMBus *vmbus;
    unsigned refcount;
};

/*
 * Wrap sequential read from / write to GPADL.
 */
typedef struct GpadlIter {
    VMBusGpadl *gpadl;
    AddressSpace *as;
    DMADirection dir;
    /* offset into GPADL where the next i/o will be performed */
    uint32_t off;
    /*
     * Cached mapping of the currently accessed page, up to page boundary.
     * Updated lazily on i/o.
     * Note: MemoryRegionCache can not be used here because pages in the GPADL
     * are non-contiguous and may belong to different memory regions.
     */
    void *map;
    /* offset after last i/o (i.e. not affected by seek) */
    uint32_t last_off;
    /*
     * Indicator that the iterator is active and may have a cached mapping.
     * Allows to enforce bracketing of all i/o (which may create cached
     * mappings) and thus exclude mapping leaks.
     */
    bool active;
} GpadlIter;

/*
 * Ring buffer.  There are two of them, sitting in the same GPADL, for each
 * channel.
 * Each ring buffer consists of a set of pages, with the first page containing
 * the ring buffer header, and the remaining pages being for data packets.
 */
typedef struct VMBusRingBufCommon {
    AddressSpace *as;
    /* GPA of the ring buffer header */
    dma_addr_t rb_addr;
    /* start and length of the ring buffer data area within GPADL */
    uint32_t base;
    uint32_t len;

    GpadlIter iter;
} VMBusRingBufCommon;

typedef struct VMBusSendRingBuf {
    VMBusRingBufCommon common;
    /* current write index, to be committed at the end of send */
    uint32_t wr_idx;
    /* write index at the start of send */
    uint32_t last_wr_idx;
    /* space to be requested from the guest */
    uint32_t wanted;
    /* space reserved for planned sends */
    uint32_t reserved;
    /* last seen read index */
    uint32_t last_seen_rd_idx;
} VMBusSendRingBuf;

typedef struct VMBusRecvRingBuf {
    VMBusRingBufCommon common;
    /* current read index, to be committed at the end of receive */
    uint32_t rd_idx;
    /* read index at the start of receive */
    uint32_t last_rd_idx;
    /* last seen write index */
    uint32_t last_seen_wr_idx;
} VMBusRecvRingBuf;


enum {
    VMOFFER_INIT,
    VMOFFER_SENDING,
    VMOFFER_SENT,
};

enum {
    VMCHAN_INIT,
    VMCHAN_OPENING,
    VMCHAN_OPEN,
};

struct VMBusChannel {
    VMBusDevice *dev;

    /* channel id */
    uint32_t id;
    /*
     * subchannel index within the device; subchannel #0 is "primary" and
     * always exists
     */
    uint16_t subchan_idx;
    uint32_t open_id;
    /* VP_INDEX of the vCPU to notify with (synthetic) interrupts */
    uint32_t target_vp;
    /* GPADL id to use for the ring buffers */
    uint32_t ringbuf_gpadl;
    /* start (in pages) of the send ring buffer within @ringbuf_gpadl */
    uint32_t ringbuf_send_offset;

    uint8_t offer_state;
    uint8_t state;
    bool is_open;

    /* main device worker; copied from the device class */
    VMBusChannelNotifyCb notify_cb;
    /*
     * guest->host notifications, either sent directly or dispatched via
     * interrupt page (older VMBus)
     */
    EventNotifier notifier;

    VMBus *vmbus;
    /*
     * SINT route to signal with host->guest notifications; may be shared with
     * the main VMBus SINT route
     */
    HvSintRoute *notify_route;
    VMBusGpadl *gpadl;

    VMBusSendRingBuf send_ringbuf;
    VMBusRecvRingBuf recv_ringbuf;

    QTAILQ_ENTRY(VMBusChannel) link;
};

/*
 * Hyper-V spec mandates that every message port has 16 buffers, which means
 * that the guest can post up to this many messages without blocking.
 * Therefore a queue for incoming messages has to be provided.
 * For outgoing (i.e. host->guest) messages there's no queue; the VMBus just
 * doesn't transition to a new state until the message is known to have been
 * successfully delivered to the respective SynIC message slot.
 */
#define HV_MSG_QUEUE_LEN     16

/* Hyper-V devices never use channel #0.  Must be something special. */
#define VMBUS_FIRST_CHANID      1
/* Each channel occupies one bit within a single event page sint slot. */
#define VMBUS_CHANID_COUNT      (HV_EVENT_FLAGS_COUNT - VMBUS_FIRST_CHANID)
/* Leave a few connection numbers for other purposes. */
#define VMBUS_CHAN_CONNECTION_OFFSET     16

/*
 * Since the success or failure of sending a message is reported
 * asynchronously, the VMBus state machine has effectively two entry points:
 * vmbus_run and vmbus_msg_cb (the latter is called when the host->guest
 * message delivery status becomes known).  Both are run as oneshot BHs on the
 * main aio context, ensuring serialization.
 */
enum {
    VMBUS_LISTEN,
    VMBUS_HANDSHAKE,
    VMBUS_OFFER,
    VMBUS_CREATE_GPADL,
    VMBUS_TEARDOWN_GPADL,
    VMBUS_OPEN_CHANNEL,
    VMBUS_UNLOAD,
    VMBUS_STATE_MAX
};

struct VMBus {
    BusState parent;

    uint8_t state;
    /* protection against recursive aio_poll (see vmbus_run) */
    bool in_progress;
    /* whether there's a message being delivered to the guest */
    bool msg_in_progress;
    uint32_t version;
    /* VP_INDEX of the vCPU to send messages and interrupts to */
    uint32_t target_vp;
    HvSintRoute *sint_route;
    /*
     * interrupt page for older protocol versions; newer ones use SynIC event
     * flags directly
     */
    hwaddr int_page_gpa;

    DECLARE_BITMAP(chanid_bitmap, VMBUS_CHANID_COUNT);

    /* incoming message queue */
    struct hyperv_post_message_input rx_queue[HV_MSG_QUEUE_LEN];
    uint8_t rx_queue_head;
    uint8_t rx_queue_size;
    QemuMutex rx_queue_lock;

    QTAILQ_HEAD(, VMBusGpadl) gpadl_list;
    QTAILQ_HEAD(, VMBusChannel) channel_list;

    /*
     * guest->host notifications for older VMBus, to be dispatched via
     * interrupt page
     */
    EventNotifier notifier;
};

static bool gpadl_full(VMBusGpadl *gpadl)
{
    return gpadl->seen_gfns == gpadl->num_gfns;
}

static VMBusGpadl *create_gpadl(VMBus *vmbus, uint32_t id,
                                uint32_t child_relid, uint32_t num_gfns)
{
    VMBusGpadl *gpadl = g_new0(VMBusGpadl, 1);

    gpadl->id = id;
    gpadl->child_relid = child_relid;
    gpadl->num_gfns = num_gfns;
    gpadl->gfns = g_new(uint64_t, num_gfns);
    QTAILQ_INSERT_HEAD(&vmbus->gpadl_list, gpadl, link);
    gpadl->vmbus = vmbus;
    gpadl->refcount = 1;
    return gpadl;
}

static void free_gpadl(VMBusGpadl *gpadl)
{
    QTAILQ_REMOVE(&gpadl->vmbus->gpadl_list, gpadl, link);
    g_free(gpadl->gfns);
    g_free(gpadl);
}

static VMBusGpadl *find_gpadl(VMBus *vmbus, uint32_t gpadl_id)
{
    VMBusGpadl *gpadl;
    QTAILQ_FOREACH(gpadl, &vmbus->gpadl_list, link) {
        if (gpadl->id == gpadl_id) {
            return gpadl;
        }
    }
    return NULL;
}

VMBusGpadl *vmbus_get_gpadl(VMBusChannel *chan, uint32_t gpadl_id)
{
    VMBusGpadl *gpadl = find_gpadl(chan->vmbus, gpadl_id);
    if (!gpadl || !gpadl_full(gpadl)) {
        return NULL;
    }
    gpadl->refcount++;
    return gpadl;
}

void vmbus_put_gpadl(VMBusGpadl *gpadl)
{
    if (!gpadl) {
        return;
    }
    if (--gpadl->refcount) {
        return;
    }
    free_gpadl(gpadl);
}

uint32_t vmbus_gpadl_len(VMBusGpadl *gpadl)
{
    return gpadl->num_gfns * TARGET_PAGE_SIZE;
}

static void gpadl_iter_init(GpadlIter *iter, VMBusGpadl *gpadl,
                            AddressSpace *as, DMADirection dir)
{
    iter->gpadl = gpadl;
    iter->as = as;
    iter->dir = dir;
    iter->active = false;
}

static inline void gpadl_iter_cache_unmap(GpadlIter *iter)
{
    uint32_t map_start_in_page = (uintptr_t)iter->map & ~TARGET_PAGE_MASK;
    uint32_t io_end_in_page = ((iter->last_off - 1) & ~TARGET_PAGE_MASK) + 1;

    /* mapping is only done to do non-zero amount of i/o */
    assert(iter->last_off > 0);
    assert(map_start_in_page < io_end_in_page);

    dma_memory_unmap(iter->as, iter->map, TARGET_PAGE_SIZE - map_start_in_page,
                     iter->dir, io_end_in_page - map_start_in_page);
}

/*
 * Copy exactly @len bytes between the GPADL pointed to by @iter and @buf.
 * The direction of the copy is determined by @iter->dir.
 * The caller must ensure the operation overflows neither @buf nor the GPADL
 * (there's an assert for the latter).
 * Reuse the currently mapped page in the GPADL if possible.
 */
static ssize_t gpadl_iter_io(GpadlIter *iter, void *buf, uint32_t len)
{
    ssize_t ret = len;

    assert(iter->active);

    while (len) {
        uint32_t off_in_page = iter->off & ~TARGET_PAGE_MASK;
        uint32_t pgleft = TARGET_PAGE_SIZE - off_in_page;
        uint32_t cplen = MIN(pgleft, len);
        void *p;

        /* try to reuse the cached mapping */
        if (iter->map) {
            uint32_t map_start_in_page =
                (uintptr_t)iter->map & ~TARGET_PAGE_MASK;
            uint32_t off_base = iter->off & ~TARGET_PAGE_MASK;
            uint32_t mapped_base = (iter->last_off - 1) & ~TARGET_PAGE_MASK;
            if (off_base != mapped_base || off_in_page < map_start_in_page) {
                gpadl_iter_cache_unmap(iter);
                iter->map = NULL;
            }
        }

        if (!iter->map) {
            dma_addr_t maddr;
            dma_addr_t mlen = pgleft;
            uint32_t idx = iter->off >> TARGET_PAGE_BITS;
            assert(idx < iter->gpadl->num_gfns);

            maddr = (iter->gpadl->gfns[idx] << TARGET_PAGE_BITS) | off_in_page;

            iter->map = dma_memory_map(iter->as, maddr, &mlen, iter->dir);
            if (mlen != pgleft) {
                dma_memory_unmap(iter->as, iter->map, mlen, iter->dir, 0);
                iter->map = NULL;
                return -EFAULT;
            }
        }

        p = (void *)(((uintptr_t)iter->map & TARGET_PAGE_MASK) | off_in_page);
        if (iter->dir == DMA_DIRECTION_FROM_DEVICE) {
            memcpy(p, buf, cplen);
        } else {
            memcpy(buf, p, cplen);
        }

        buf += cplen;
        len -= cplen;
        iter->off += cplen;
        iter->last_off = iter->off;
    }

    return ret;
}

/*
 * Position the iterator @iter at new offset @new_off.
 * If this results in the cached mapping being unusable with the new offset,
 * unmap it.
 */
static inline void gpadl_iter_seek(GpadlIter *iter, uint32_t new_off)
{
    assert(iter->active);
    iter->off = new_off;
}

/*
 * Start a series of i/o on the GPADL.
 * After this i/o and seek operations on @iter become legal.
 */
static inline void gpadl_iter_start_io(GpadlIter *iter)
{
    assert(!iter->active);
    /* mapping is cached lazily on i/o */
    iter->map = NULL;
    iter->active = true;
}

/*
 * End the eariler started series of i/o on the GPADL and release the cached
 * mapping if any.
 */
static inline void gpadl_iter_end_io(GpadlIter *iter)
{
    assert(iter->active);

    if (iter->map) {
        gpadl_iter_cache_unmap(iter);
    }

    iter->active = false;
}

static void vmbus_resched(VMBus *vmbus);
static void vmbus_msg_cb(void *data, int status);

ssize_t vmbus_iov_to_gpadl(VMBusChannel *chan, VMBusGpadl *gpadl, uint32_t off,
                           const struct iovec *iov, size_t iov_cnt)
{
    GpadlIter iter;
    size_t i;
    ssize_t ret = 0;

    gpadl_iter_init(&iter, gpadl, chan->dev->dma_as,
                    DMA_DIRECTION_FROM_DEVICE);
    gpadl_iter_start_io(&iter);
    gpadl_iter_seek(&iter, off);
    for (i = 0; i < iov_cnt; i++) {
        ret = gpadl_iter_io(&iter, iov[i].iov_base, iov[i].iov_len);
        if (ret < 0) {
            goto out;
        }
    }
out:
    gpadl_iter_end_io(&iter);
    return ret;
}

int vmbus_map_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov,
                  unsigned iov_cnt, size_t len, size_t off)
{
    int ret_cnt = 0, ret;
    unsigned i;
    QEMUSGList *sgl = &req->sgl;
    ScatterGatherEntry *sg = sgl->sg;

    for (i = 0; i < sgl->nsg; i++) {
        if (sg[i].len > off) {
            break;
        }
        off -= sg[i].len;
    }
    for (; len && i < sgl->nsg; i++) {
        dma_addr_t mlen = MIN(sg[i].len - off, len);
        dma_addr_t addr = sg[i].base + off;
        len -= mlen;
        off = 0;

        for (; mlen; ret_cnt++) {
            dma_addr_t l = mlen;
            dma_addr_t a = addr;

            if (ret_cnt == iov_cnt) {
                ret = -ENOBUFS;
                goto err;
            }

            iov[ret_cnt].iov_base = dma_memory_map(sgl->as, a, &l, dir);
            if (!l) {
                ret = -EFAULT;
                goto err;
            }
            iov[ret_cnt].iov_len = l;
            addr += l;
            mlen -= l;
        }
    }

    return ret_cnt;
err:
    vmbus_unmap_sgl(req, dir, iov, ret_cnt, 0);
    return ret;
}

void vmbus_unmap_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov,
                     unsigned iov_cnt, size_t accessed)
{
    QEMUSGList *sgl = &req->sgl;
    unsigned i;

    for (i = 0; i < iov_cnt; i++) {
        size_t acsd = MIN(accessed, iov[i].iov_len);
        dma_memory_unmap(sgl->as, iov[i].iov_base, iov[i].iov_len, dir, acsd);
        accessed -= acsd;
    }
}

static const VMStateDescription vmstate_gpadl = {
    .name = "vmbus/gpadl",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(id, VMBusGpadl),
        VMSTATE_UINT32(child_relid, VMBusGpadl),
        VMSTATE_UINT32(num_gfns, VMBusGpadl),
        VMSTATE_UINT32(seen_gfns, VMBusGpadl),
        VMSTATE_VARRAY_UINT32_ALLOC(gfns, VMBusGpadl, num_gfns, 0,
                                    vmstate_info_uint64, uint64_t),
        VMSTATE_UINT8(state, VMBusGpadl),
        VMSTATE_END_OF_LIST()
    }
};

/*
 * Wrap the index into a ring buffer of @len bytes.
 * @idx is assumed not to exceed twice the size of the ringbuffer, so only
 * single wraparound is considered.
 */
static inline uint32_t rb_idx_wrap(uint32_t idx, uint32_t len)
{
    if (idx >= len) {
        idx -= len;
    }
    return idx;
}

/*
 * Circular difference between two indices into a ring buffer of @len bytes.
 * @allow_catchup - whether @idx1 may catch up @idx2; e.g. read index may catch
 * up write index but not vice versa.
 */
static inline uint32_t rb_idx_delta(uint32_t idx1, uint32_t idx2, uint32_t len,
                                    bool allow_catchup)
{
    return rb_idx_wrap(idx2 + len - idx1 - !allow_catchup, len);
}

static vmbus_ring_buffer *ringbuf_map_hdr(VMBusRingBufCommon *ringbuf)
{
    vmbus_ring_buffer *rb;
    dma_addr_t mlen = sizeof(*rb);

    rb = dma_memory_map(ringbuf->as, ringbuf->rb_addr, &mlen,
                        DMA_DIRECTION_FROM_DEVICE);
    if (mlen != sizeof(*rb)) {
        dma_memory_unmap(ringbuf->as, rb, mlen,
                         DMA_DIRECTION_FROM_DEVICE, 0);
        return NULL;
    }
    return rb;
}

static void ringbuf_unmap_hdr(VMBusRingBufCommon *ringbuf,
                              vmbus_ring_buffer *rb, bool dirty)
{
    assert(rb);

    dma_memory_unmap(ringbuf->as, rb, sizeof(*rb), DMA_DIRECTION_FROM_DEVICE,
                     dirty ? sizeof(*rb) : 0);
}

static void ringbuf_init_common(VMBusRingBufCommon *ringbuf, VMBusGpadl *gpadl,
                                AddressSpace *as, DMADirection dir,
                                uint32_t begin, uint32_t end)
{
    ringbuf->as = as;
    ringbuf->rb_addr = gpadl->gfns[begin] << TARGET_PAGE_BITS;
    ringbuf->base = (begin + 1) << TARGET_PAGE_BITS;
    ringbuf->len = (end - begin - 1) << TARGET_PAGE_BITS;
    gpadl_iter_init(&ringbuf->iter, gpadl, as, dir);
}

static int ringbufs_init(VMBusChannel *chan)
{
    vmbus_ring_buffer *rb;
    VMBusSendRingBuf *send_ringbuf = &chan->send_ringbuf;
    VMBusRecvRingBuf *recv_ringbuf = &chan->recv_ringbuf;

    if (chan->ringbuf_send_offset <= 1 ||
        chan->gpadl->num_gfns <= chan->ringbuf_send_offset + 1) {
        return -EINVAL;
    }

    ringbuf_init_common(&recv_ringbuf->common, chan->gpadl, chan->dev->dma_as,
                        DMA_DIRECTION_TO_DEVICE, 0, chan->ringbuf_send_offset);
    ringbuf_init_common(&send_ringbuf->common, chan->gpadl, chan->dev->dma_as,
                        DMA_DIRECTION_FROM_DEVICE, chan->ringbuf_send_offset,
                        chan->gpadl->num_gfns);
    send_ringbuf->wanted = 0;
    send_ringbuf->reserved = 0;

    rb = ringbuf_map_hdr(&recv_ringbuf->common);
    if (!rb) {
        return -EFAULT;
    }
    recv_ringbuf->rd_idx = recv_ringbuf->last_rd_idx = rb->read_index;
    ringbuf_unmap_hdr(&recv_ringbuf->common, rb, false);

    rb = ringbuf_map_hdr(&send_ringbuf->common);
    if (!rb) {
        return -EFAULT;
    }
    send_ringbuf->wr_idx = send_ringbuf->last_wr_idx = rb->write_index;
    send_ringbuf->last_seen_rd_idx = rb->read_index;
    rb->feature_bits |= VMBUS_RING_BUFFER_FEAT_PENDING_SZ;
    ringbuf_unmap_hdr(&send_ringbuf->common, rb, true);

    if (recv_ringbuf->rd_idx >= recv_ringbuf->common.len ||
        send_ringbuf->wr_idx >= send_ringbuf->common.len) {
        return -EOVERFLOW;
    }

    return 0;
}

/*
 * Perform io between the GPADL-backed ringbuffer @ringbuf and @buf, wrapping
 * around if needed.
 * @len is assumed not to exceed the size of the ringbuffer, so only single
 * wraparound is considered.
 */
static ssize_t ringbuf_io(VMBusRingBufCommon *ringbuf, void *buf, uint32_t len)
{
    ssize_t ret1 = 0, ret2 = 0;
    uint32_t remain = ringbuf->len + ringbuf->base - ringbuf->iter.off;

    if (len >= remain) {
        ret1 = gpadl_iter_io(&ringbuf->iter, buf, remain);
        if (ret1 < 0) {
            return ret1;
        }
        gpadl_iter_seek(&ringbuf->iter, ringbuf->base);
        buf += remain;
        len -= remain;
    }
    ret2 = gpadl_iter_io(&ringbuf->iter, buf, len);
    if (ret2 < 0) {
        return ret2;
    }
    return ret1 + ret2;
}

/*
 * Position the circular iterator within @ringbuf to offset @new_off, wrapping
 * around if needed.
 * @new_off is assumed not to exceed twice the size of the ringbuffer, so only
 * single wraparound is considered.
 */
static inline void ringbuf_seek(VMBusRingBufCommon *ringbuf, uint32_t new_off)
{
    gpadl_iter_seek(&ringbuf->iter,
                    ringbuf->base + rb_idx_wrap(new_off, ringbuf->len));
}

static inline uint32_t ringbuf_tell(VMBusRingBufCommon *ringbuf)
{
    return ringbuf->iter.off - ringbuf->base;
}

static inline void ringbuf_start_io(VMBusRingBufCommon *ringbuf)
{
    gpadl_iter_start_io(&ringbuf->iter);
}

static inline void ringbuf_end_io(VMBusRingBufCommon *ringbuf)
{
    gpadl_iter_end_io(&ringbuf->iter);
}

VMBusDevice *vmbus_channel_device(VMBusChannel *chan)
{
    return chan->dev;
}

VMBusChannel *vmbus_device_channel(VMBusDevice *dev, uint32_t chan_idx)
{
    if (chan_idx >= dev->num_channels) {
        return NULL;
    }
    return &dev->channels[chan_idx];
}

uint32_t vmbus_channel_idx(VMBusChannel *chan)
{
    return chan - chan->dev->channels;
}

void vmbus_channel_notify_host(VMBusChannel *chan)
{
    event_notifier_set(&chan->notifier);
}

bool vmbus_channel_is_open(VMBusChannel *chan)
{
    return chan->is_open;
}

/*
 * Notify the guest side about the data to work on in the channel ring buffer.
 * The notification is done by signaling a dedicated per-channel SynIC event
 * flag (more recent guests) or setting a bit in the interrupt page and firing
 * the VMBus SINT (older guests).
 */
static int vmbus_channel_notify_guest(VMBusChannel *chan)
{
    int res = 0;
    unsigned long *int_map, mask;
    unsigned idx;
    hwaddr addr = chan->vmbus->int_page_gpa;
    hwaddr len = TARGET_PAGE_SIZE / 2, dirty = 0;

    trace_vmbus_channel_notify_guest(chan->id);

    if (!addr) {
        return hyperv_set_event_flag(chan->notify_route, chan->id);
    }

    int_map = cpu_physical_memory_map(addr, &len, 1);
    if (len != TARGET_PAGE_SIZE / 2) {
        res = -ENXIO;
        goto unmap;
    }

    idx = BIT_WORD(chan->id);
    mask = BIT_MASK(chan->id);
    if ((atomic_fetch_or(&int_map[idx], mask) & mask) != mask) {
        res = hyperv_sint_route_set_sint(chan->notify_route);
        dirty = len;
    }

unmap:
    cpu_physical_memory_unmap(int_map, len, 1, dirty);
    return res;
}

#define VMBUS_PKT_TRAILER      sizeof(uint64_t)

static uint32_t vmbus_pkt_hdr_set_offsets(vmbus_packet_hdr *hdr,
                                          uint32_t desclen, uint32_t msglen)
{
    hdr->offset_qwords = sizeof(*hdr) / sizeof(uint64_t) +
        DIV_ROUND_UP(desclen, sizeof(uint64_t));
    hdr->len_qwords = hdr->offset_qwords +
        DIV_ROUND_UP(msglen, sizeof(uint64_t));
    return hdr->len_qwords * sizeof(uint64_t) + VMBUS_PKT_TRAILER;
}

/*
 * Simplified ring buffer operation with paired barriers annotations in the
 * producer and consumer loops:
 *
 * producer                           * consumer
 * ~~~~~~~~                           * ~~~~~~~~
 * write pending_send_sz              * read write_index
 * smp_mb                       [A]   * smp_mb                       [C]
 * read read_index                    * read packet
 * smp_mb                       [B]   * read/write out-of-band data
 * read/write out-of-band data        * smp_mb                       [B]
 * write packet                       * write read_index
 * smp_mb                       [C]   * smp_mb                       [A]
 * write write_index                  * read pending_send_sz
 * smp_wmb                      [D]   * smp_rmb                      [D]
 * write pending_send_sz              * read write_index
 * ...                                * ...
 */

static inline uint32_t ringbuf_send_avail(VMBusSendRingBuf *ringbuf)
{
    /* don't trust guest data */
    if (ringbuf->last_seen_rd_idx >= ringbuf->common.len) {
        return 0;
    }
    return rb_idx_delta(ringbuf->wr_idx, ringbuf->last_seen_rd_idx,
                        ringbuf->common.len, false);
}

static ssize_t ringbuf_send_update_idx(VMBusChannel *chan)
{
    VMBusSendRingBuf *ringbuf = &chan->send_ringbuf;
    vmbus_ring_buffer *rb;
    uint32_t written;

    written = rb_idx_delta(ringbuf->last_wr_idx, ringbuf->wr_idx,
                           ringbuf->common.len, true);
    if (!written) {
        return 0;
    }

    rb = ringbuf_map_hdr(&ringbuf->common);
    if (!rb) {
        return -EFAULT;
    }

    ringbuf->reserved -= written;

    /* prevent reorder with the data operation and packet write */
    smp_mb();                   /* barrier pair [C] */
    rb->write_index = ringbuf->wr_idx;

    /*
     * If the producer earlier indicated that it wants to be notified when the
     * consumer frees certain amount of space in the ring buffer, that amount
     * is reduced by the size of the completed write.
     */
    if (ringbuf->wanted) {
        /* otherwise reservation would fail */
        assert(ringbuf->wanted < written);
        ringbuf->wanted -= written;
        /* prevent reorder with write_index write */
        smp_wmb();              /* barrier pair [D] */
        rb->pending_send_sz = ringbuf->wanted;
    }

    /* prevent reorder with write_index or pending_send_sz write */
    smp_mb();                   /* barrier pair [A] */
    ringbuf->last_seen_rd_idx = rb->read_index;

    /*
     * The consumer may have missed the reduction of pending_send_sz and skip
     * notification, so re-check the blocking condition, and, if it's no longer
     * true, ensure processing another iteration by simulating consumer's
     * notification.
     */
    if (ringbuf_send_avail(ringbuf) >= ringbuf->wanted) {
        vmbus_channel_notify_host(chan);
    }

    /* skip notification by consumer's request */
    if (rb->interrupt_mask) {
        goto out;
    }

    /*
     * The consumer hasn't caught up with the producer's previous state so it's
     * not blocked.
     * (last_seen_rd_idx comes from the guest but it's safe to use w/o
     * validation here as it only affects notification.)
     */
    if (rb_idx_delta(ringbuf->last_seen_rd_idx, ringbuf->wr_idx,
                     ringbuf->common.len, true) > written) {
        goto out;
    }

    vmbus_channel_notify_guest(chan);
out:
    ringbuf_unmap_hdr(&ringbuf->common, rb, true);
    ringbuf->last_wr_idx = ringbuf->wr_idx;
    return written;
}

int vmbus_channel_reserve(VMBusChannel *chan,
                          uint32_t desclen, uint32_t msglen)
{
    VMBusSendRingBuf *ringbuf = &chan->send_ringbuf;
    vmbus_ring_buffer *rb = NULL;
    vmbus_packet_hdr hdr;
    uint32_t needed = ringbuf->reserved +
        vmbus_pkt_hdr_set_offsets(&hdr, desclen, msglen);

    /* avoid touching the guest memory if possible */
    if (likely(needed <= ringbuf_send_avail(ringbuf))) {
        goto success;
    }

    rb = ringbuf_map_hdr(&ringbuf->common);
    if (!rb) {
        return -EFAULT;
    }

    /* fetch read index from guest memory and try again */
    ringbuf->last_seen_rd_idx = rb->read_index;

    if (likely(needed <= ringbuf_send_avail(ringbuf))) {
        goto success;
    }

    rb->pending_send_sz = needed;

    /*
     * The consumer may have made progress and freed up some space before
     * seeing updated pending_send_sz, so re-read read_index (preventing
     * reorder with the pending_send_sz write) and try again.
     */
    smp_mb();                   /* barrier pair [A] */
    ringbuf->last_seen_rd_idx = rb->read_index;

    if (needed > ringbuf_send_avail(ringbuf)) {
        goto out;
    }

success:
    ringbuf->reserved = needed;
    needed = 0;

    /* clear pending_send_sz if it was set */
    if (ringbuf->wanted) {
        if (!rb) {
            rb = ringbuf_map_hdr(&ringbuf->common);
            if (!rb) {
                /* failure to clear pending_send_sz is non-fatal */
                goto out;
            }
        }

        rb->pending_send_sz = 0;
    }

    /* prevent reorder of the following data operation with read_index read */
    smp_mb();                   /* barrier pair [B] */

out:
    if (rb) {
        ringbuf_unmap_hdr(&ringbuf->common, rb, ringbuf->wanted == needed);
    }
    ringbuf->wanted = needed;
    return needed ? -ENOSPC : 0;
}

ssize_t vmbus_channel_send(VMBusChannel *chan, uint16_t pkt_type,
                           void *desc, uint32_t desclen,
                           void *msg, uint32_t msglen,
                           bool need_comp, uint64_t transaction_id)
{
    ssize_t ret = 0;
    vmbus_packet_hdr hdr;
    uint32_t totlen;
    VMBusSendRingBuf *ringbuf = &chan->send_ringbuf;

    if (!vmbus_channel_is_open(chan)) {
        return -EINVAL;
    }

    totlen = vmbus_pkt_hdr_set_offsets(&hdr, desclen, msglen);
    hdr.type = pkt_type;
    hdr.flags = need_comp ? VMBUS_PACKET_FLAG_REQUEST_COMPLETION : 0;
    hdr.transaction_id = transaction_id;

    assert(totlen <= ringbuf->reserved);

    ringbuf_start_io(&ringbuf->common);
    ringbuf_seek(&ringbuf->common, ringbuf->wr_idx);
    ret = ringbuf_io(&ringbuf->common, &hdr, sizeof(hdr));
    if (ret < 0) {
        goto out;
    }
    if (desclen) {
        assert(desc);
        ret = ringbuf_io(&ringbuf->common, desc, desclen);
        if (ret < 0) {
            goto out;
        }
        ringbuf_seek(&ringbuf->common,
                     ringbuf->wr_idx + hdr.offset_qwords * sizeof(uint64_t));
    }
    ret = ringbuf_io(&ringbuf->common, msg, msglen);
    if (ret < 0) {
        goto out;
    }
    ringbuf_seek(&ringbuf->common, ringbuf->wr_idx + totlen);
    ringbuf->wr_idx = ringbuf_tell(&ringbuf->common);
    ret = 0;
out:
    ringbuf_end_io(&ringbuf->common);
    if (ret) {
        return ret;
    }
    return ringbuf_send_update_idx(chan);
}

ssize_t vmbus_channel_send_completion(VMBusChanReq *req,
                                      void *msg, uint32_t msglen)
{
    assert(req->need_comp);
    return vmbus_channel_send(req->chan, VMBUS_PACKET_COMP, NULL, 0,
                              msg, msglen, false, req->transaction_id);
}

static int sgl_from_gpa_ranges(QEMUSGList *sgl, VMBusDevice *dev,
                               VMBusRingBufCommon *ringbuf, uint32_t len)
{
    int ret;
    vmbus_pkt_gpa_direct hdr;
    hwaddr curaddr = 0;
    hwaddr curlen = 0;
    int num;

    if (len < sizeof(hdr)) {
        return -EIO;
    }
    ret = ringbuf_io(ringbuf, &hdr, sizeof(hdr));
    if (ret < 0) {
        return ret;
    }
    len -= sizeof(hdr);

    num = (len - hdr.rangecount * sizeof(vmbus_gpa_range)) / sizeof(uint64_t);
    if (num < 0) {
        return -EIO;
    }
    qemu_sglist_init(sgl, DEVICE(dev), num, ringbuf->as);

    for (; hdr.rangecount; hdr.rangecount--) {
        vmbus_gpa_range range;

        if (len < sizeof(range)) {
            goto eio;
        }
        ret = ringbuf_io(ringbuf, &range, sizeof(range));
        if (ret < 0) {
            goto err;
        }
        len -= sizeof(range);

        if (range.byte_offset & TARGET_PAGE_MASK) {
            goto eio;
        }

        for (; range.byte_count; range.byte_offset = 0) {
            uint64_t paddr;
            uint32_t plen = MIN(range.byte_count,
                                TARGET_PAGE_SIZE - range.byte_offset);

            if (len < sizeof(uint64_t)) {
                goto eio;
            }
            ret = ringbuf_io(ringbuf, &paddr, sizeof(paddr));
            if (ret < 0) {
                goto err;
            }
            len -= sizeof(uint64_t);
            paddr <<= TARGET_PAGE_BITS;
            paddr |= range.byte_offset;
            range.byte_count -= plen;

            if (curaddr + curlen == paddr) {
                /* consecutive fragments - join */
                curlen += plen;
            } else {
                if (curlen) {
                    qemu_sglist_add(sgl, curaddr, curlen);
                }

                curaddr = paddr;
                curlen = plen;
            }
        }
    }

    if (curlen) {
        qemu_sglist_add(sgl, curaddr, curlen);
    }

    return 0;
eio:
    ret = -EIO;
err:
    qemu_sglist_destroy(sgl);
    return ret;
}

static VMBusChanReq *vmbus_alloc_req(VMBusChannel *chan,
                                     uint32_t size, uint16_t pkt_type,
                                     uint32_t msglen, uint64_t transaction_id,
                                     bool need_comp)
{
    VMBusChanReq *req;
    uint32_t msgoff = QEMU_ALIGN_UP(size, __alignof__(*req->msg));
    uint32_t totlen = msgoff + msglen;

    req = g_malloc0(totlen);
    req->chan = chan;
    req->pkt_type = pkt_type;
    req->msg = (void *)req + msgoff;
    req->msglen = msglen;
    req->transaction_id = transaction_id;
    req->need_comp = need_comp;
    return req;
}

int vmbus_channel_recv_start(VMBusChannel *chan)
{
    VMBusRecvRingBuf *ringbuf = &chan->recv_ringbuf;
    vmbus_ring_buffer *rb;

    rb = ringbuf_map_hdr(&ringbuf->common);
    if (!rb) {
        return -EFAULT;
    }
    ringbuf->last_seen_wr_idx = rb->write_index;
    ringbuf_unmap_hdr(&ringbuf->common, rb, false);

    if (ringbuf->last_seen_wr_idx >= ringbuf->common.len) {
        return -EOVERFLOW;
    }

    /* prevent reorder of the following data operation with write_index read */
    smp_mb();                   /* barrier pair [C] */
    return 0;
}

void *vmbus_channel_recv_peek(VMBusChannel *chan, uint32_t size)
{
    VMBusRecvRingBuf *ringbuf = &chan->recv_ringbuf;
    vmbus_packet_hdr hdr = {};
    VMBusChanReq *req;
    uint32_t avail;
    uint32_t totlen, pktlen, msglen, msgoff, desclen;

    assert(size >= sizeof(*req));

    /* safe as last_seen_wr_idx is validated in vmbus_channel_recv_start */
    avail = rb_idx_delta(ringbuf->rd_idx, ringbuf->last_seen_wr_idx,
                         ringbuf->common.len, true);
    if (avail < sizeof(hdr)) {
        return NULL;
    }

    ringbuf_seek(&ringbuf->common, ringbuf->rd_idx);
    if (ringbuf_io(&ringbuf->common, &hdr, sizeof(hdr)) < 0) {
        return NULL;
    }

    pktlen = hdr.len_qwords * sizeof(uint64_t);
    totlen = pktlen + VMBUS_PKT_TRAILER;
    if (totlen > avail) {
        return NULL;
    }

    msgoff = hdr.offset_qwords * sizeof(uint64_t);
    if (msgoff > pktlen || msgoff < sizeof(hdr)) {
        error_report("%s: malformed packet: %u %u", __func__, msgoff, pktlen);
        return NULL;
    }

    msglen = pktlen - msgoff;

    req = vmbus_alloc_req(chan, size, hdr.type, msglen, hdr.transaction_id,
                          hdr.flags & VMBUS_PACKET_FLAG_REQUEST_COMPLETION);

    switch (hdr.type) {
    case VMBUS_PACKET_DATA_USING_GPA_DIRECT:
        desclen = msgoff - sizeof(hdr);
        if (sgl_from_gpa_ranges(&req->sgl, chan->dev, &ringbuf->common,
                                desclen) < 0) {
            error_report("%s: failed to convert GPA ranges to SGL", __func__);
            goto free_req;
        }
        break;
    case VMBUS_PACKET_DATA_INBAND:
    case VMBUS_PACKET_COMP:
        break;
    default:
        error_report("%s: unexpected msg type: %x", __func__, hdr.type);
        goto free_req;
    }

    ringbuf_seek(&ringbuf->common, ringbuf->rd_idx + msgoff);
    if (ringbuf_io(&ringbuf->common, req->msg, msglen) < 0) {
        goto free_req;
    }
    ringbuf_seek(&ringbuf->common, ringbuf->rd_idx + totlen);

    return req;
free_req:
    vmbus_free_req(req);
    return NULL;
}

void vmbus_channel_recv_pop(VMBusChannel *chan)
{
    VMBusRecvRingBuf *ringbuf = &chan->recv_ringbuf;
    ringbuf->rd_idx = ringbuf_tell(&ringbuf->common);
}

ssize_t vmbus_channel_recv_done(VMBusChannel *chan)
{
    VMBusRecvRingBuf *ringbuf = &chan->recv_ringbuf;
    vmbus_ring_buffer *rb;
    uint32_t read;

    read = rb_idx_delta(ringbuf->last_rd_idx, ringbuf->rd_idx,
                        ringbuf->common.len, true);
    if (!read) {
        return 0;
    }

    rb = ringbuf_map_hdr(&ringbuf->common);
    if (!rb) {
        return -EFAULT;
    }

    /* prevent reorder with the data operation and packet read */
    smp_mb();                   /* barrier pair [B] */
    rb->read_index = ringbuf->rd_idx;

    /* prevent reorder of the following pending_send_sz read */
    smp_mb();                   /* barrier pair [A] */

    if (rb->interrupt_mask) {
        goto out;
    }

    if (rb->feature_bits & VMBUS_RING_BUFFER_FEAT_PENDING_SZ) {
        uint32_t wr_idx, wr_avail;
        uint32_t wanted = rb->pending_send_sz;

        if (!wanted) {
            goto out;
        }

        /* prevent reorder with pending_send_sz read */
        smp_rmb();              /* barrier pair [D] */
        wr_idx = rb->write_index;

        wr_avail = rb_idx_delta(wr_idx, ringbuf->rd_idx, ringbuf->common.len,
                                true);

        /* the producer wasn't blocked on the consumer state */
        if (wr_avail >= read + wanted) {
            goto out;
        }
        /* there's not enough space for the producer to make progress */
        if (wr_avail < wanted) {
            goto out;
        }
    }

    vmbus_channel_notify_guest(chan);
out:
    ringbuf_unmap_hdr(&ringbuf->common, rb, true);
    ringbuf->last_rd_idx = ringbuf->rd_idx;
    return read;
}

void vmbus_free_req(void *req)
{
    VMBusChanReq *r = req;

    if (!req) {
        return;
    }

    if (r->sgl.dev) {
        qemu_sglist_destroy(&r->sgl);
    }
    g_free(req);
}

static const VMStateDescription vmstate_sgent = {
    .name = "vmbus/sgentry",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(base, ScatterGatherEntry),
        VMSTATE_UINT64(len, ScatterGatherEntry),
        VMSTATE_END_OF_LIST()
    }
};

typedef struct VMBusChanReqSave {
    uint16_t chan_idx;
    uint16_t pkt_type;
    uint32_t msglen;
    void *msg;
    uint64_t transaction_id;
    bool need_comp;
    uint32_t num;
    ScatterGatherEntry *sgl;
} VMBusChanReqSave;

static const VMStateDescription vmstate_vmbus_chan_req = {
    .name = "vmbus/vmbus_chan_req",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT16(chan_idx, VMBusChanReqSave),
        VMSTATE_UINT16(pkt_type, VMBusChanReqSave),
        VMSTATE_UINT32(msglen, VMBusChanReqSave),
        VMSTATE_VBUFFER_ALLOC_UINT32(msg, VMBusChanReqSave, 0, NULL, msglen),
        VMSTATE_UINT64(transaction_id, VMBusChanReqSave),
        VMSTATE_BOOL(need_comp, VMBusChanReqSave),
        VMSTATE_UINT32(num, VMBusChanReqSave),
        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(sgl, VMBusChanReqSave, num,
                                             vmstate_sgent, ScatterGatherEntry),
        VMSTATE_END_OF_LIST()
    }
};

void vmbus_save_req(QEMUFile *f, VMBusChanReq *req)
{
    VMBusChanReqSave req_save;

    req_save.chan_idx = req->chan->subchan_idx;
    req_save.pkt_type = req->pkt_type;
    req_save.msglen = req->msglen;
    req_save.msg = req->msg;
    req_save.transaction_id = req->transaction_id;
    req_save.need_comp = req->need_comp;
    req_save.num = req->sgl.nsg;
    req_save.sgl = g_memdup(req->sgl.sg,
                            req_save.num * sizeof(ScatterGatherEntry));

    vmstate_save_state(f, &vmstate_vmbus_chan_req, &req_save, NULL);

    g_free(req_save.sgl);
}

void *vmbus_load_req(QEMUFile *f, VMBusDevice *dev, uint32_t size)
{
    VMBusChanReqSave req_save;
    VMBusChanReq *req = NULL;
    VMBusChannel *chan = NULL;
    uint32_t i;

    vmstate_load_state(f, &vmstate_vmbus_chan_req, &req_save, 0);

    if (req_save.chan_idx >= dev->num_channels) {
        error_report("%s: %u(chan_idx) > %u(num_channels)", __func__,
                     req_save.chan_idx, dev->num_channels);
        goto out;
    }
    chan = &dev->channels[req_save.chan_idx];

    if (vmbus_channel_reserve(chan, 0, req_save.msglen)) {
        goto out;
    }

    req = vmbus_alloc_req(chan, size, req_save.pkt_type, req_save.msglen,
                          req_save.transaction_id, req_save.need_comp);
    if (req_save.msglen) {
        memcpy(req->msg, req_save.msg, req_save.msglen);
    }

    for (i = 0; i < req_save.num; i++) {
        qemu_sglist_add(&req->sgl, req_save.sgl[i].base, req_save.sgl[i].len);
    }

out:
    if (req_save.msglen) {
        g_free(req_save.msg);
    }
    if (req_save.num) {
        g_free(req_save.sgl);
    }
    return req;
}

static void channel_event_cb(EventNotifier *e)
{
    VMBusChannel *chan = container_of(e, VMBusChannel, notifier);
    if (event_notifier_test_and_clear(e)) {
        /*
         * All receives are supposed to happen within the device worker, so
         * bracket it with ringbuf_start/end_io on the receive ringbuffer, and
         * potentially reuse the cached mapping throughout the worker.
         * Can't do this for sends as they may happen outside the device
         * worker.
         */
        VMBusRecvRingBuf *ringbuf = &chan->recv_ringbuf;
        ringbuf_start_io(&ringbuf->common);
        chan->notify_cb(chan);
        ringbuf_end_io(&ringbuf->common);

    }
}

static int alloc_chan_id(VMBus *vmbus)
{
    int ret;

    ret = find_next_zero_bit(vmbus->chanid_bitmap, VMBUS_CHANID_COUNT, 0);
    if (ret == VMBUS_CHANID_COUNT) {
        return -ENOMEM;
    }
    return ret + VMBUS_FIRST_CHANID;
}

static int register_chan_id(VMBusChannel *chan)
{
    return test_and_set_bit(chan->id - VMBUS_FIRST_CHANID,
                            chan->vmbus->chanid_bitmap) ? -EEXIST : 0;
}

static void unregister_chan_id(VMBusChannel *chan)
{
    clear_bit(chan->id - VMBUS_FIRST_CHANID, chan->vmbus->chanid_bitmap);
}

static uint32_t chan_connection_id(VMBusChannel *chan)
{
    return VMBUS_CHAN_CONNECTION_OFFSET + chan->id;
}

static void init_channel(VMBus *vmbus, VMBusDevice *dev, VMBusDeviceClass *vdc,
                         VMBusChannel *chan, uint16_t idx, Error **errp)
{
    int res;

    chan->dev = dev;
    chan->notify_cb = vdc->chan_notify_cb;
    chan->subchan_idx = idx;
    chan->vmbus = vmbus;

    res = alloc_chan_id(vmbus);
    if (res < 0) {
        error_setg(errp, "no spare channel id");
        return;
    }
    chan->id = res;
    register_chan_id(chan);

    /*
     * The guest drivers depend on the device subchannels (idx #1+) to be
     * offered after the primary channel (idx #0) of that device.  To ensure
     * that, record the channels on the channel list in the order they appear
     * within the device.
     */
    QTAILQ_INSERT_TAIL(&vmbus->channel_list, chan, link);
}

static void deinit_channel(VMBusChannel *chan)
{
    assert(chan->state == VMCHAN_INIT);
    QTAILQ_REMOVE(&chan->vmbus->channel_list, chan, link);
    unregister_chan_id(chan);
}

static void create_channels(VMBus *vmbus, VMBusDevice *dev, Error **errp)
{
    uint16_t i;
    VMBusDeviceClass *vdc = VMBUS_DEVICE_GET_CLASS(dev);
    Error *err = NULL;

    dev->num_channels = vdc->num_channels ? vdc->num_channels(dev) : 1;
    if (dev->num_channels < 1) {
        error_setg(errp, "invalid #channels: %u", dev->num_channels);
        return;
    }

    dev->channels = g_new0(VMBusChannel, dev->num_channels);
    for (i = 0; i < dev->num_channels; i++) {
        init_channel(vmbus, dev, vdc, &dev->channels[i], i, &err);
        if (err) {
            goto err_init;
        }
    }

    return;

err_init:
    while (i--) {
        deinit_channel(&dev->channels[i]);
    }
    error_propagate(errp, err);
}

static void free_channels(VMBusDevice *dev)
{
    uint16_t i;
    for (i = 0; i < dev->num_channels; i++) {
        deinit_channel(&dev->channels[i]);
    }
    g_free(dev->channels);
}

static HvSintRoute *make_sint_route(VMBus *vmbus, uint32_t vp_index)
{
    VMBusChannel *chan;

    if (vp_index == vmbus->target_vp) {
        hyperv_sint_route_ref(vmbus->sint_route);
        return vmbus->sint_route;
    }

    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (chan->target_vp == vp_index && vmbus_channel_is_open(chan)) {
            hyperv_sint_route_ref(chan->notify_route);
            return chan->notify_route;
        }
    }

    return hyperv_sint_route_new(vp_index, VMBUS_SINT, NULL, NULL);
}

static void open_channel(VMBusChannel *chan)
{
    VMBusDeviceClass *vdc = VMBUS_DEVICE_GET_CLASS(chan->dev);

    chan->gpadl = vmbus_get_gpadl(chan, chan->ringbuf_gpadl);
    if (!chan->gpadl) {
        return;
    }

    if (ringbufs_init(chan)) {
        goto put_gpadl;
    }

    if (event_notifier_init(&chan->notifier, 0)) {
        goto put_gpadl;
    }

    event_notifier_set_handler(&chan->notifier, channel_event_cb);

    if (hyperv_set_event_flag_handler(chan_connection_id(chan),
                                      &chan->notifier)) {
        goto cleanup_notifier;
    }

    chan->notify_route = make_sint_route(chan->vmbus, chan->target_vp);
    if (!chan->notify_route) {
        goto clear_event_flag_handler;
    }

    if (vdc->open_channel && vdc->open_channel(chan)) {
        goto unref_sint_route;
    }

    chan->is_open = true;
    return;

unref_sint_route:
    hyperv_sint_route_unref(chan->notify_route);
clear_event_flag_handler:
    hyperv_set_event_flag_handler(chan_connection_id(chan), NULL);
cleanup_notifier:
    event_notifier_set_handler(&chan->notifier, NULL);
    event_notifier_cleanup(&chan->notifier);
put_gpadl:
    vmbus_put_gpadl(chan->gpadl);
}

static void close_channel(VMBusChannel *chan)
{
    VMBusDeviceClass *vdc = VMBUS_DEVICE_GET_CLASS(chan->dev);

    if (!chan->is_open) {
        return;
    }

    if (vdc->close_channel) {
        vdc->close_channel(chan);
    }

    hyperv_sint_route_unref(chan->notify_route);
    hyperv_set_event_flag_handler(chan_connection_id(chan), NULL);
    event_notifier_set_handler(&chan->notifier, NULL);
    event_notifier_cleanup(&chan->notifier);
    vmbus_put_gpadl(chan->gpadl);
    chan->is_open = false;
}

static int channel_post_load(void *opaque, int version_id)
{
    VMBusChannel *chan = opaque;

    return register_chan_id(chan);
}

static const VMStateDescription vmstate_channel = {
    .name = "vmbus/channel",
    .version_id = 0,
    .minimum_version_id = 0,
    .post_load = channel_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(id, VMBusChannel),
        VMSTATE_UINT16(subchan_idx, VMBusChannel),
        VMSTATE_UINT32(open_id, VMBusChannel),
        VMSTATE_UINT32(target_vp, VMBusChannel),
        VMSTATE_UINT32(ringbuf_gpadl, VMBusChannel),
        VMSTATE_UINT32(ringbuf_send_offset, VMBusChannel),
        VMSTATE_UINT8(offer_state, VMBusChannel),
        VMSTATE_UINT8(state, VMBusChannel),
        VMSTATE_END_OF_LIST()
    }
};

static VMBusChannel *find_channel(VMBus *vmbus, uint32_t id)
{
    VMBusChannel *chan;
    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (chan->id == id) {
            return chan;
        }
    }
    return NULL;
}

static int enqueue_incoming_message(VMBus *vmbus,
                                    const struct hyperv_post_message_input *msg)
{
    int ret = 0;
    uint8_t idx, prev_size;

    qemu_mutex_lock(&vmbus->rx_queue_lock);

    if (vmbus->rx_queue_size == HV_MSG_QUEUE_LEN) {
        ret = -ENOBUFS;
        goto out;
    }

    prev_size = vmbus->rx_queue_size;
    idx = (vmbus->rx_queue_head + vmbus->rx_queue_size) % HV_MSG_QUEUE_LEN;
    memcpy(&vmbus->rx_queue[idx], msg, sizeof(*msg));
    vmbus->rx_queue_size++;

    /* only need to resched if the queue was empty before */
    if (!prev_size) {
        vmbus_resched(vmbus);
    }
out:
    qemu_mutex_unlock(&vmbus->rx_queue_lock);
    return ret;
}

static uint16_t vmbus_recv_message(const struct hyperv_post_message_input *msg,
                                   void *data)
{
    VMBus *vmbus = data;
    struct vmbus_message_header *vmbus_msg;

    if (msg->message_type != HV_MESSAGE_VMBUS) {
        return HV_STATUS_INVALID_HYPERCALL_INPUT;
    }

    if (msg->payload_size < sizeof(struct vmbus_message_header)) {
        return HV_STATUS_INVALID_HYPERCALL_INPUT;
    }

    vmbus_msg = (struct vmbus_message_header *)msg->payload;

    trace_vmbus_recv_message(vmbus_msg->message_type, msg->payload_size);

    if (vmbus_msg->message_type == VMBUS_MSG_INVALID ||
        vmbus_msg->message_type >= VMBUS_MSG_COUNT) {
        error_report("vmbus: unknown message type %#x",
                     vmbus_msg->message_type);
        return HV_STATUS_INVALID_HYPERCALL_INPUT;
    }

    if (enqueue_incoming_message(vmbus, msg)) {
        return HV_STATUS_INSUFFICIENT_BUFFERS;
    }
    return HV_STATUS_SUCCESS;
}

static bool vmbus_initialized(VMBus *vmbus)
{
    return vmbus->version > 0 && vmbus->version <= VMBUS_VERSION_CURRENT;
}

static void vmbus_reset_all(VMBus *vmbus)
{
    qbus_reset_all(BUS(vmbus));
}

static void post_msg(VMBus *vmbus, void *msgdata, uint32_t msglen)
{
    int ret;
    struct hyperv_message msg = {
        .header.message_type = HV_MESSAGE_VMBUS,
    };

    assert(!vmbus->msg_in_progress);
    assert(msglen <= sizeof(msg.payload));
    assert(msglen >= sizeof(struct vmbus_message_header));

    vmbus->msg_in_progress = true;

    trace_vmbus_post_msg(((struct vmbus_message_header *)msgdata)->message_type,
                         msglen);

    memcpy(msg.payload, msgdata, msglen);
    msg.header.payload_size = ROUND_UP(msglen, VMBUS_MESSAGE_SIZE_ALIGN);

    ret = hyperv_post_msg(vmbus->sint_route, &msg);
    if (ret == 0 || ret == -EAGAIN) {
        return;
    }

    error_report("message delivery fatal failure: %d; aborting vmbus", ret);
    vmbus_reset_all(vmbus);
}

static int vmbus_init(VMBus *vmbus)
{
    if (vmbus->target_vp != (uint32_t)-1) {
        vmbus->sint_route = hyperv_sint_route_new(vmbus->target_vp, VMBUS_SINT,
                                                  vmbus_msg_cb, vmbus);
        if (!vmbus->sint_route) {
            error_report("failed to set up SINT route");
            return -ENOMEM;
        }
    }
    return 0;
}

static void vmbus_deinit(VMBus *vmbus)
{
    VMBusGpadl *gpadl, *tmp_gpadl;
    VMBusChannel *chan;

    QTAILQ_FOREACH_SAFE(gpadl, &vmbus->gpadl_list, link, tmp_gpadl) {
        if (gpadl->state == VMGPADL_TORNDOWN) {
            continue;
        }
        vmbus_put_gpadl(gpadl);
    }

    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        chan->offer_state = VMOFFER_INIT;
    }

    hyperv_sint_route_unref(vmbus->sint_route);
    vmbus->sint_route = NULL;
    vmbus->int_page_gpa = 0;
    vmbus->target_vp = (uint32_t)-1;
    vmbus->version = 0;
    vmbus->state = VMBUS_LISTEN;
    vmbus->msg_in_progress = false;
}

static void handle_initiate_contact(VMBus *vmbus,
                                    vmbus_message_initiate_contact *msg,
                                    uint32_t msglen)
{
    if (msglen < sizeof(*msg)) {
        return;
    }

    trace_vmbus_initiate_contact(msg->version_requested >> 16,
                                 msg->version_requested & 0xffff,
                                 msg->target_vcpu, msg->monitor_page1,
                                 msg->monitor_page2, msg->interrupt_page);

    /*
     * Reset vmbus on INITIATE_CONTACT regardless of its previous state.
     * Useful, in particular, with vmbus-aware BIOS which can't shut vmbus down
     * before handing over to OS loader.
     */
    vmbus_reset_all(vmbus);

    vmbus->target_vp = msg->target_vcpu;
    vmbus->version = msg->version_requested;
    if (vmbus->version < VMBUS_VERSION_WIN8) {
        /* linux passes interrupt page even when it doesn't need it */
        vmbus->int_page_gpa = msg->interrupt_page;
    }
    vmbus->state = VMBUS_HANDSHAKE;

    if (vmbus_init(vmbus)) {
        error_report("failed to init vmbus; aborting");
        vmbus_deinit(vmbus);
        return;
    }
}

static void send_handshake(VMBus *vmbus)
{
    struct vmbus_message_version_response msg = {
        .header.message_type = VMBUS_MSG_VERSION_RESPONSE,
        .version_supported = vmbus_initialized(vmbus),
    };

    post_msg(vmbus, &msg, sizeof(msg));
}

static void handle_request_offers(VMBus *vmbus, void *msgdata, uint32_t msglen)
{
    VMBusChannel *chan;

    if (!vmbus_initialized(vmbus)) {
        return;
    }

    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (chan->offer_state == VMOFFER_INIT) {
            chan->offer_state = VMOFFER_SENDING;
            break;
        }
    }

    vmbus->state = VMBUS_OFFER;
}

static void send_offer(VMBus *vmbus)
{
    VMBusChannel *chan;
    struct vmbus_message_header alloffers_msg = {
        .message_type = VMBUS_MSG_ALLOFFERS_DELIVERED,
    };

    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (chan->offer_state == VMOFFER_SENDING) {
            VMBusDeviceClass *vdc = VMBUS_DEVICE_GET_CLASS(chan->dev);
            /* Hyper-V wants LE GUIDs */
            QemuUUID classid = qemu_uuid_bswap(vdc->classid);
            QemuUUID instanceid = qemu_uuid_bswap(chan->dev->instanceid);
            struct vmbus_message_offer_channel msg = {
                .header.message_type = VMBUS_MSG_OFFERCHANNEL,
                .child_relid = chan->id,
                .connection_id = chan_connection_id(chan),
                .channel_flags = vdc->channel_flags,
                .mmio_size_mb = vdc->mmio_size_mb,
                .sub_channel_index = vmbus_channel_idx(chan),
                .interrupt_flags = VMBUS_OFFER_INTERRUPT_DEDICATED,
            };

            memcpy(msg.type_uuid, &classid, sizeof(classid));
            memcpy(msg.instance_uuid, &instanceid, sizeof(instanceid));

            trace_vmbus_send_offer(chan->id, chan->dev);

            post_msg(vmbus, &msg, sizeof(msg));
            return;
        }
    }

    /* no more offers, send terminator message */
    trace_vmbus_terminate_offers();
    post_msg(vmbus, &alloffers_msg, sizeof(alloffers_msg));
}

static bool complete_offer(VMBus *vmbus)
{
    VMBusChannel *chan;

    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (chan->offer_state == VMOFFER_SENDING) {
            chan->offer_state = VMOFFER_SENT;
            goto next_offer;
        }
    }
    /*
     * no transitioning channels found so this is completing the terminator
     * message, and vmbus can move to the next state
     */
    return true;

next_offer:
    /* try to mark another channel for offering */
    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (chan->offer_state == VMOFFER_INIT) {
            chan->offer_state = VMOFFER_SENDING;
            break;
        }
    }
    /*
     * if an offer has been sent there are more offers or the terminator yet to
     * send, so no state transition for vmbus
     */
    return false;
}


static void handle_gpadl_header(VMBus *vmbus, vmbus_message_gpadl_header *msg,
                                uint32_t msglen)
{
    VMBusGpadl *gpadl;
    uint32_t num_gfns, i;

    /* must include at least one gpa range */
    if (msglen < sizeof(*msg) + sizeof(msg->range[0]) ||
        !vmbus_initialized(vmbus)) {
        return;
    }

    num_gfns = (msg->range_buflen - msg->rangecount * sizeof(msg->range[0])) /
               sizeof(msg->range[0].pfn_array[0]);

    trace_vmbus_gpadl_header(msg->gpadl_id, num_gfns);

    /*
     * In theory the GPADL_HEADER message can define a GPADL with multiple GPA
     * ranges each with arbitrary size and alignment.  However in practice only
     * single-range page-aligned GPADLs have been observed so just ignore
     * anything else and simplify things greatly.
     */
    if (msg->rangecount != 1 || msg->range[0].byte_offset ||
        (msg->range[0].byte_count != (num_gfns << TARGET_PAGE_BITS))) {
        return;
    }

    /* ignore requests to create already existing GPADLs */
    if (find_gpadl(vmbus, msg->gpadl_id)) {
        return;
    }

    gpadl = create_gpadl(vmbus, msg->gpadl_id, msg->child_relid, num_gfns);

    for (i = 0; i < num_gfns &&
         (void *)&msg->range[0].pfn_array[i + 1] <= (void *)msg + msglen;
         i++) {
        gpadl->gfns[gpadl->seen_gfns++] = msg->range[0].pfn_array[i];
    }

    if (gpadl_full(gpadl)) {
        vmbus->state = VMBUS_CREATE_GPADL;
    }
}

static void handle_gpadl_body(VMBus *vmbus, vmbus_message_gpadl_body *msg,
                              uint32_t msglen)
{
    VMBusGpadl *gpadl;
    uint32_t num_gfns_left, i;

    if (msglen < sizeof(*msg) || !vmbus_initialized(vmbus)) {
        return;
    }

    trace_vmbus_gpadl_body(msg->gpadl_id);

    gpadl = find_gpadl(vmbus, msg->gpadl_id);
    if (!gpadl) {
        return;
    }

    num_gfns_left = gpadl->num_gfns - gpadl->seen_gfns;
    assert(num_gfns_left);

    for (i = 0; i < num_gfns_left &&
         (void *)&msg->pfn_array[i + 1] <= (void *)msg + msglen; i++) {
        gpadl->gfns[gpadl->seen_gfns++] = msg->pfn_array[i];
    }

    if (gpadl_full(gpadl)) {
        vmbus->state = VMBUS_CREATE_GPADL;
    }
}

static void send_create_gpadl(VMBus *vmbus)
{
    VMBusGpadl *gpadl;

    QTAILQ_FOREACH(gpadl, &vmbus->gpadl_list, link) {
        if (gpadl_full(gpadl) && gpadl->state == VMGPADL_INIT) {
            struct vmbus_message_gpadl_created msg = {
                .header.message_type = VMBUS_MSG_GPADL_CREATED,
                .gpadl_id = gpadl->id,
                .child_relid = gpadl->child_relid,
            };

            trace_vmbus_gpadl_created(gpadl->id);
            post_msg(vmbus, &msg, sizeof(msg));
            return;
        }
    }

    assert(false);
}

static bool complete_create_gpadl(VMBus *vmbus)
{
    VMBusGpadl *gpadl;

    QTAILQ_FOREACH(gpadl, &vmbus->gpadl_list, link) {
        if (gpadl_full(gpadl) && gpadl->state == VMGPADL_INIT) {
            gpadl->state = VMGPADL_ALIVE;

            return true;
        }
    }

    assert(false);
    return false;
}

static void handle_gpadl_teardown(VMBus *vmbus,
                                  vmbus_message_gpadl_teardown *msg,
                                  uint32_t msglen)
{
    VMBusGpadl *gpadl;

    if (msglen < sizeof(*msg) || !vmbus_initialized(vmbus)) {
        return;
    }

    trace_vmbus_gpadl_teardown(msg->gpadl_id);

    gpadl = find_gpadl(vmbus, msg->gpadl_id);
    if (!gpadl || gpadl->state == VMGPADL_TORNDOWN) {
        return;
    }

    gpadl->state = VMGPADL_TEARINGDOWN;
    vmbus->state = VMBUS_TEARDOWN_GPADL;
}

static void send_teardown_gpadl(VMBus *vmbus)
{
    VMBusGpadl *gpadl;

    QTAILQ_FOREACH(gpadl, &vmbus->gpadl_list, link) {
        if (gpadl->state == VMGPADL_TEARINGDOWN) {
            struct vmbus_message_gpadl_torndown msg = {
                .header.message_type = VMBUS_MSG_GPADL_TORNDOWN,
                .gpadl_id = gpadl->id,
            };

            trace_vmbus_gpadl_torndown(gpadl->id);
            post_msg(vmbus, &msg, sizeof(msg));
            return;
        }
    }

    assert(false);
}

static bool complete_teardown_gpadl(VMBus *vmbus)
{
    VMBusGpadl *gpadl;

    QTAILQ_FOREACH(gpadl, &vmbus->gpadl_list, link) {
        if (gpadl->state == VMGPADL_TEARINGDOWN) {
            gpadl->state = VMGPADL_TORNDOWN;
            vmbus_put_gpadl(gpadl);
            return true;
        }
    }

    assert(false);
    return false;
}

static void handle_open_channel(VMBus *vmbus, vmbus_message_open_channel *msg,
                                uint32_t msglen)
{
    VMBusChannel *chan;

    if (msglen < sizeof(*msg) || !vmbus_initialized(vmbus)) {
        return;
    }

    trace_vmbus_open_channel(msg->child_relid, msg->ring_buffer_gpadl_id,
                             msg->target_vp);
    chan = find_channel(vmbus, msg->child_relid);
    if (!chan || chan->state != VMCHAN_INIT) {
        return;
    }

    chan->ringbuf_gpadl = msg->ring_buffer_gpadl_id;
    chan->ringbuf_send_offset = msg->ring_buffer_offset;
    chan->target_vp = msg->target_vp;
    chan->open_id = msg->open_id;

    open_channel(chan);

    chan->state = VMCHAN_OPENING;
    vmbus->state = VMBUS_OPEN_CHANNEL;
}

static void send_open_channel(VMBus *vmbus)
{
    VMBusChannel *chan;

    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (chan->state == VMCHAN_OPENING) {
            struct vmbus_message_open_result msg = {
                .header.message_type = VMBUS_MSG_OPENCHANNEL_RESULT,
                .child_relid = chan->id,
                .open_id = chan->open_id,
                .status = !vmbus_channel_is_open(chan),
            };

            trace_vmbus_channel_open(chan->id, msg.status);
            post_msg(vmbus, &msg, sizeof(msg));
            return;
        }
    }

    assert(false);
}

static bool complete_open_channel(VMBus *vmbus)
{
    VMBusChannel *chan;

    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (chan->state == VMCHAN_OPENING) {
            if (vmbus_channel_is_open(chan)) {
                chan->state = VMCHAN_OPEN;
                /*
                 * simulate guest notification of ringbuffer space made
                 * available, for the channel protocols where the host
                 * initiates the communication
                 */
                vmbus_channel_notify_host(chan);
            } else {
                chan->state = VMCHAN_INIT;
            }
            return true;
        }
    }

    assert(false);
    return false;
}

static void vdev_reset_on_close(VMBusDevice *vdev)
{
    uint16_t i;

    for (i = 0; i < vdev->num_channels; i++) {
        if (vmbus_channel_is_open(&vdev->channels[i])) {
            return;
        }
    }

    /* all channels closed -- reset device */
    qdev_reset_all(DEVICE(vdev));
}

static void handle_close_channel(VMBus *vmbus, vmbus_message_close_channel *msg,
                                 uint32_t msglen)
{
    VMBusChannel *chan;

    if (msglen < sizeof(*msg) || !vmbus_initialized(vmbus)) {
        return;
    }

    trace_vmbus_close_channel(msg->child_relid);

    chan = find_channel(vmbus, msg->child_relid);
    if (!chan) {
        return;
    }

    close_channel(chan);
    chan->state = VMCHAN_INIT;

    vdev_reset_on_close(chan->dev);
}

static void handle_unload(VMBus *vmbus, void *msg, uint32_t msglen)
{
    vmbus->state = VMBUS_UNLOAD;
}

static void send_unload(VMBus *vmbus)
{
    vmbus_message_header msg = {
        .message_type = VMBUS_MSG_UNLOAD_RESPONSE,
    };

    qemu_mutex_lock(&vmbus->rx_queue_lock);
    vmbus->rx_queue_size = 0;
    qemu_mutex_unlock(&vmbus->rx_queue_lock);

    post_msg(vmbus, &msg, sizeof(msg));
    return;
}

static bool complete_unload(VMBus *vmbus)
{
    vmbus_reset_all(vmbus);
    return true;
}

static void process_message(VMBus *vmbus)
{
    struct hyperv_post_message_input *hv_msg;
    struct vmbus_message_header *msg;
    void *msgdata;
    uint32_t msglen;

    qemu_mutex_lock(&vmbus->rx_queue_lock);

    if (!vmbus->rx_queue_size) {
        goto unlock;
    }

    hv_msg = &vmbus->rx_queue[vmbus->rx_queue_head];
    msglen =  hv_msg->payload_size;
    if (msglen < sizeof(*msg)) {
        goto out;
    }
    msgdata = hv_msg->payload;
    msg = (struct vmbus_message_header *)msgdata;

    trace_vmbus_process_incoming_message(msg->message_type);

    switch (msg->message_type) {
    case VMBUS_MSG_INITIATE_CONTACT:
        handle_initiate_contact(vmbus, msgdata, msglen);
        break;
    case VMBUS_MSG_REQUESTOFFERS:
        handle_request_offers(vmbus, msgdata, msglen);
        break;
    case VMBUS_MSG_GPADL_HEADER:
        handle_gpadl_header(vmbus, msgdata, msglen);
        break;
    case VMBUS_MSG_GPADL_BODY:
        handle_gpadl_body(vmbus, msgdata, msglen);
        break;
    case VMBUS_MSG_GPADL_TEARDOWN:
        handle_gpadl_teardown(vmbus, msgdata, msglen);
        break;
    case VMBUS_MSG_OPENCHANNEL:
        handle_open_channel(vmbus, msgdata, msglen);
        break;
    case VMBUS_MSG_CLOSECHANNEL:
        handle_close_channel(vmbus, msgdata, msglen);
        break;
    case VMBUS_MSG_UNLOAD:
        handle_unload(vmbus, msgdata, msglen);
        break;
    default:
        error_report("unknown message type %#x", msg->message_type);
        break;
    }

out:
    vmbus->rx_queue_size--;
    vmbus->rx_queue_head++;
    vmbus->rx_queue_head %= HV_MSG_QUEUE_LEN;

    vmbus_resched(vmbus);
unlock:
    qemu_mutex_unlock(&vmbus->rx_queue_lock);
}

static const struct {
    void (*run)(VMBus *vmbus);
    bool (*complete)(VMBus *vmbus);
} state_runner[] = {
    [VMBUS_LISTEN]         = {process_message,     NULL},
    [VMBUS_HANDSHAKE]      = {send_handshake,      NULL},
    [VMBUS_OFFER]          = {send_offer,          complete_offer},
    [VMBUS_CREATE_GPADL]   = {send_create_gpadl,   complete_create_gpadl},
    [VMBUS_TEARDOWN_GPADL] = {send_teardown_gpadl, complete_teardown_gpadl},
    [VMBUS_OPEN_CHANNEL]   = {send_open_channel,   complete_open_channel},
    [VMBUS_UNLOAD]         = {send_unload,         complete_unload},
};

static void vmbus_do_run(VMBus *vmbus)
{
    if (vmbus->msg_in_progress) {
        return;
    }

    assert(vmbus->state < VMBUS_STATE_MAX);
    assert(state_runner[vmbus->state].run);
    state_runner[vmbus->state].run(vmbus);
}

static void vmbus_run(void *opaque)
{
    VMBus *vmbus = opaque;

    /* make sure no recursion happens (e.g. due to recursive aio_poll()) */
    if (vmbus->in_progress) {
        return;
    }

    vmbus->in_progress = true;
    /*
     * FIXME: if vmbus_resched() is called from within vmbus_do_run(), it
     * should go *after* the code that can result in aio_poll; otherwise
     * reschedules can be missed.  No idea how to enforce that.
     */
    vmbus_do_run(vmbus);
    vmbus->in_progress = false;
}

static void vmbus_msg_cb(void *data, int status)
{
    VMBus *vmbus = data;
    bool (*complete)(VMBus *vmbus);

    assert(vmbus->msg_in_progress);

    trace_vmbus_msg_cb(status);

    if (status == -EAGAIN) {
        goto out;
    }
    if (status) {
        error_report("message delivery fatal failure: %d; aborting vmbus",
                     status);
        vmbus_reset_all(vmbus);
        return;
    }

    assert(vmbus->state < VMBUS_STATE_MAX);
    complete = state_runner[vmbus->state].complete;
    if (!complete || complete(vmbus)) {
        vmbus->state = VMBUS_LISTEN;
    }
out:
    vmbus->msg_in_progress = false;
    vmbus_resched(vmbus);
}

static void vmbus_resched(VMBus *vmbus)
{
    aio_bh_schedule_oneshot(qemu_get_aio_context(), vmbus_run, vmbus);
}

static void vmbus_signal_event(EventNotifier *e)
{
    VMBusChannel *chan;
    VMBus *vmbus = container_of(e, VMBus, notifier);
    unsigned long *int_map;
    hwaddr addr, len;
    bool is_dirty = false;

    if (!event_notifier_test_and_clear(e)) {
        return;
    }

    trace_vmbus_signal_event();

    if (!vmbus->int_page_gpa) {
        return;
    }

    addr = vmbus->int_page_gpa + TARGET_PAGE_SIZE / 2;
    len = TARGET_PAGE_SIZE / 2;
    int_map = cpu_physical_memory_map(addr, &len, 1);
    if (len != TARGET_PAGE_SIZE / 2) {
        goto unmap;
    }

    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        if (bitmap_test_and_clear_atomic(int_map, chan->id, 1)) {
            if (!vmbus_channel_is_open(chan)) {
                continue;
            }
            vmbus_channel_notify_host(chan);
            is_dirty = true;
        }
    }

unmap:
    cpu_physical_memory_unmap(int_map, len, 1, is_dirty);
}

static void vmbus_dev_realize(DeviceState *dev, Error **errp)
{
    VMBusDevice *vdev = VMBUS_DEVICE(dev);
    VMBusDeviceClass *vdc = VMBUS_DEVICE_GET_CLASS(vdev);
    VMBus *vmbus = VMBUS(qdev_get_parent_bus(dev));
    BusChild *child;
    Error *err = NULL;
    char idstr[UUID_FMT_LEN + 1];

    assert(!qemu_uuid_is_null(&vdev->instanceid));

    /* Check for instance id collision for this class id */
    QTAILQ_FOREACH(child, &BUS(vmbus)->children, sibling) {
        VMBusDevice *child_dev = VMBUS_DEVICE(child->child);

        if (child_dev == vdev) {
            continue;
        }

        if (qemu_uuid_is_equal(&child_dev->instanceid, &vdev->instanceid)) {
            qemu_uuid_unparse(&vdev->instanceid, idstr);
            error_setg(&err, "duplicate vmbus device instance id %s", idstr);
            goto error_out;
        }
    }

    vdev->dma_as = &address_space_memory;

    create_channels(vmbus, vdev, &err);
    if (err) {
        goto error_out;
    }

    if (vdc->vmdev_realize) {
        vdc->vmdev_realize(vdev, &err);
        if (err) {
            goto err_vdc_realize;
        }
    }
    return;

err_vdc_realize:
    free_channels(vdev);
error_out:
    error_propagate(errp, err);
}

static void vmbus_dev_reset(DeviceState *dev)
{
    uint16_t i;
    VMBusDevice *vdev = VMBUS_DEVICE(dev);
    VMBusDeviceClass *vdc = VMBUS_DEVICE_GET_CLASS(vdev);

    if (vdev->channels) {
        for (i = 0; i < vdev->num_channels; i++) {
            VMBusChannel *chan = &vdev->channels[i];
            close_channel(chan);
            chan->state = VMCHAN_INIT;
        }
    }

    if (vdc->vmdev_reset) {
        vdc->vmdev_reset(vdev);
    }
}

static void vmbus_dev_unrealize(DeviceState *dev)
{
    VMBusDevice *vdev = VMBUS_DEVICE(dev);
    VMBusDeviceClass *vdc = VMBUS_DEVICE_GET_CLASS(vdev);

    if (vdc->vmdev_unrealize) {
        vdc->vmdev_unrealize(vdev);
    }
    free_channels(vdev);
}

static void vmbus_dev_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *kdev = DEVICE_CLASS(klass);
    kdev->bus_type = TYPE_VMBUS;
    kdev->realize = vmbus_dev_realize;
    kdev->unrealize = vmbus_dev_unrealize;
    kdev->reset = vmbus_dev_reset;
}

static Property vmbus_dev_instanceid =
                        DEFINE_PROP_UUID("instanceid", VMBusDevice, instanceid);

static void vmbus_dev_instance_init(Object *obj)
{
    VMBusDevice *vdev = VMBUS_DEVICE(obj);
    VMBusDeviceClass *vdc = VMBUS_DEVICE_GET_CLASS(vdev);

    if (!qemu_uuid_is_null(&vdc->instanceid)) {
        /* Class wants to only have a single instance with a fixed UUID */
        vdev->instanceid = vdc->instanceid;
    } else {
        qdev_property_add_static(DEVICE(vdev), &vmbus_dev_instanceid);
    }
}

const VMStateDescription vmstate_vmbus_dev = {
    .name = TYPE_VMBUS_DEVICE,
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8_ARRAY(instanceid.data, VMBusDevice, 16),
        VMSTATE_UINT16(num_channels, VMBusDevice),
        VMSTATE_STRUCT_VARRAY_POINTER_UINT16(channels, VMBusDevice,
                                             num_channels, vmstate_channel,
                                             VMBusChannel),
        VMSTATE_END_OF_LIST()
    }
};

/* vmbus generic device base */
static const TypeInfo vmbus_dev_type_info = {
    .name = TYPE_VMBUS_DEVICE,
    .parent = TYPE_DEVICE,
    .abstract = true,
    .instance_size = sizeof(VMBusDevice),
    .class_size = sizeof(VMBusDeviceClass),
    .class_init = vmbus_dev_class_init,
    .instance_init = vmbus_dev_instance_init,
};

static void vmbus_realize(BusState *bus, Error **errp)
{
    int ret = 0;
    Error *local_err = NULL;
    VMBus *vmbus = VMBUS(bus);

    qemu_mutex_init(&vmbus->rx_queue_lock);

    QTAILQ_INIT(&vmbus->gpadl_list);
    QTAILQ_INIT(&vmbus->channel_list);

    ret = hyperv_set_msg_handler(VMBUS_MESSAGE_CONNECTION_ID,
                                 vmbus_recv_message, vmbus);
    if (ret != 0) {
        error_setg(&local_err, "hyperv set message handler failed: %d", ret);
        goto error_out;
    }

    ret = event_notifier_init(&vmbus->notifier, 0);
    if (ret != 0) {
        error_setg(&local_err, "event notifier failed to init with %d", ret);
        goto remove_msg_handler;
    }

    event_notifier_set_handler(&vmbus->notifier, vmbus_signal_event);
    ret = hyperv_set_event_flag_handler(VMBUS_EVENT_CONNECTION_ID,
                                        &vmbus->notifier);
    if (ret != 0) {
        error_setg(&local_err, "hyperv set event handler failed with %d", ret);
        goto clear_event_notifier;
    }

    return;

clear_event_notifier:
    event_notifier_cleanup(&vmbus->notifier);
remove_msg_handler:
    hyperv_set_msg_handler(VMBUS_MESSAGE_CONNECTION_ID, NULL, NULL);
error_out:
    qemu_mutex_destroy(&vmbus->rx_queue_lock);
    error_propagate(errp, local_err);
}

static void vmbus_unrealize(BusState *bus)
{
    VMBus *vmbus = VMBUS(bus);

    hyperv_set_msg_handler(VMBUS_MESSAGE_CONNECTION_ID, NULL, NULL);
    hyperv_set_event_flag_handler(VMBUS_EVENT_CONNECTION_ID, NULL);
    event_notifier_cleanup(&vmbus->notifier);

    qemu_mutex_destroy(&vmbus->rx_queue_lock);
}

static void vmbus_reset(BusState *bus)
{
    vmbus_deinit(VMBUS(bus));
}

static char *vmbus_get_dev_path(DeviceState *dev)
{
    BusState *bus = qdev_get_parent_bus(dev);
    return qdev_get_dev_path(bus->parent);
}

static char *vmbus_get_fw_dev_path(DeviceState *dev)
{
    VMBusDevice *vdev = VMBUS_DEVICE(dev);
    char uuid[UUID_FMT_LEN + 1];

    qemu_uuid_unparse(&vdev->instanceid, uuid);
    return g_strdup_printf("%s@%s", qdev_fw_name(dev), uuid);
}

static void vmbus_class_init(ObjectClass *klass, void *data)
{
    BusClass *k = BUS_CLASS(klass);

    k->get_dev_path = vmbus_get_dev_path;
    k->get_fw_dev_path = vmbus_get_fw_dev_path;
    k->realize = vmbus_realize;
    k->unrealize = vmbus_unrealize;
    k->reset = vmbus_reset;
}

static int vmbus_pre_load(void *opaque)
{
    VMBusChannel *chan;
    VMBus *vmbus = VMBUS(opaque);

    /*
     * channel IDs allocated by the source will come in the migration stream
     * for each channel, so clean up the ones allocated at realize
     */
    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {
        unregister_chan_id(chan);
    }

    return 0;
}
static int vmbus_post_load(void *opaque, int version_id)
{
    int ret;
    VMBus *vmbus = VMBUS(opaque);
    VMBusGpadl *gpadl;
    VMBusChannel *chan;

    ret = vmbus_init(vmbus);
    if (ret) {
        return ret;
    }

    QTAILQ_FOREACH(gpadl, &vmbus->gpadl_list, link) {
        gpadl->vmbus = vmbus;
        gpadl->refcount = 1;
    }

    /*
     * reopening channels depends on initialized vmbus so it's done here
     * instead of channel_post_load()
     */
    QTAILQ_FOREACH(chan, &vmbus->channel_list, link) {

        if (chan->state == VMCHAN_OPENING || chan->state == VMCHAN_OPEN) {
            open_channel(chan);
        }

        if (chan->state != VMCHAN_OPEN) {
            continue;
        }

        if (!vmbus_channel_is_open(chan)) {
            /* reopen failed, abort loading */
            return -1;
        }

        /* resume processing on the guest side if it missed the notification */
        hyperv_sint_route_set_sint(chan->notify_route);
        /* ditto on the host side */
        vmbus_channel_notify_host(chan);
    }

    vmbus_resched(vmbus);
    return 0;
}

static const VMStateDescription vmstate_post_message_input = {
    .name = "vmbus/hyperv_post_message_input",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        /*
         * skip connection_id and message_type as they are validated before
         * queueing and ignored on dequeueing
         */
        VMSTATE_UINT32(payload_size, struct hyperv_post_message_input),
        VMSTATE_UINT8_ARRAY(payload, struct hyperv_post_message_input,
                            HV_MESSAGE_PAYLOAD_SIZE),
        VMSTATE_END_OF_LIST()
    }
};

static bool vmbus_rx_queue_needed(void *opaque)
{
    VMBus *vmbus = VMBUS(opaque);
    return vmbus->rx_queue_size;
}

static const VMStateDescription vmstate_rx_queue = {
    .name = "vmbus/rx_queue",
    .version_id = 0,
    .minimum_version_id = 0,
    .needed = vmbus_rx_queue_needed,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(rx_queue_head, VMBus),
        VMSTATE_UINT8(rx_queue_size, VMBus),
        VMSTATE_STRUCT_ARRAY(rx_queue, VMBus,
                             HV_MSG_QUEUE_LEN, 0,
                             vmstate_post_message_input,
                             struct hyperv_post_message_input),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_vmbus = {
    .name = TYPE_VMBUS,
    .version_id = 0,
    .minimum_version_id = 0,
    .pre_load = vmbus_pre_load,
    .post_load = vmbus_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(state, VMBus),
        VMSTATE_UINT32(version, VMBus),
        VMSTATE_UINT32(target_vp, VMBus),
        VMSTATE_UINT64(int_page_gpa, VMBus),
        VMSTATE_QTAILQ_V(gpadl_list, VMBus, 0,
                         vmstate_gpadl, VMBusGpadl, link),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription * []) {
        &vmstate_rx_queue,
        NULL
    }
};

static const TypeInfo vmbus_type_info = {
    .name = TYPE_VMBUS,
    .parent = TYPE_BUS,
    .instance_size = sizeof(VMBus),
    .class_init = vmbus_class_init,
};

static void vmbus_bridge_realize(DeviceState *dev, Error **errp)
{
    VMBusBridge *bridge = VMBUS_BRIDGE(dev);

    /*
     * here there's at least one vmbus bridge that is being realized, so
     * vmbus_bridge_find can only return NULL if it's not unique
     */
    if (!vmbus_bridge_find()) {
        error_setg(errp, "there can be at most one %s in the system",
                   TYPE_VMBUS_BRIDGE);
        return;
    }

    if (!hyperv_is_synic_enabled()) {
        error_report("VMBus requires usable Hyper-V SynIC and VP_INDEX");
        return;
    }

    bridge->bus = VMBUS(qbus_create(TYPE_VMBUS, dev, "vmbus"));
}

static char *vmbus_bridge_ofw_unit_address(const SysBusDevice *dev)
{
    /* there can be only one VMBus */
    return g_strdup("0");
}

static const VMStateDescription vmstate_vmbus_bridge = {
    .name = TYPE_VMBUS_BRIDGE,
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT_POINTER(bus, VMBusBridge, vmstate_vmbus, VMBus),
        VMSTATE_END_OF_LIST()
    },
};

static Property vmbus_bridge_props[] = {
    DEFINE_PROP_UINT8("irq", VMBusBridge, irq, 7),
    DEFINE_PROP_END_OF_LIST()
};

static void vmbus_bridge_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *k = DEVICE_CLASS(klass);
    SysBusDeviceClass *sk = SYS_BUS_DEVICE_CLASS(klass);

    k->realize = vmbus_bridge_realize;
    k->fw_name = "vmbus";
    sk->explicit_ofw_unit_address = vmbus_bridge_ofw_unit_address;
    set_bit(DEVICE_CATEGORY_BRIDGE, k->categories);
    k->vmsd = &vmstate_vmbus_bridge;
    device_class_set_props(k, vmbus_bridge_props);
    /* override SysBusDevice's default */
    k->user_creatable = true;
}

static const TypeInfo vmbus_bridge_type_info = {
    .name = TYPE_VMBUS_BRIDGE,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(VMBusBridge),
    .class_init = vmbus_bridge_class_init,
};

static void vmbus_register_types(void)
{
    type_register_static(&vmbus_bridge_type_info);
    type_register_static(&vmbus_dev_type_info);
    type_register_static(&vmbus_type_info);
}

type_init(vmbus_register_types)
