/*
 * Copyright (c) 2018  Citrix Systems Inc.
 *
 * 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/main-loop.h"
#include "qemu/module.h"
#include "qemu/uuid.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "hw/xen/xen.h"
#include "hw/xen/xen-backend.h"
#include "hw/xen/xen-bus.h"
#include "hw/xen/xen-bus-helper.h"
#include "monitor/monitor.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "sysemu/sysemu.h"
#include "net/net.h"
#include "trace.h"

static char *xen_device_get_backend_path(XenDevice *xendev)
{
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
    const char *type = object_get_typename(OBJECT(xendev));
    const char *backend = xendev_class->backend;

    if (!backend) {
        backend = type;
    }

    return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
                           xenbus->backend_id, backend, xendev->frontend_id,
                           xendev->name);
}

static char *xen_device_get_frontend_path(XenDevice *xendev)
{
    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
    const char *type = object_get_typename(OBJECT(xendev));
    const char *device = xendev_class->device;

    if (!device) {
        device = type;
    }

    return g_strdup_printf("/local/domain/%u/device/%s/%s",
                           xendev->frontend_id, device, xendev->name);
}

static void xen_device_unplug(XenDevice *xendev, Error **errp)
{
    ERRP_GUARD();
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    const char *type = object_get_typename(OBJECT(xendev));
    xs_transaction_t tid;

    trace_xen_device_unplug(type, xendev->name);

    /* Mimic the way the Xen toolstack does an unplug */
again:
    tid = qemu_xen_xs_transaction_start(xenbus->xsh);
    if (tid == XBT_NULL) {
        error_setg_errno(errp, errno, "failed xs_transaction_start");
        return;
    }

    xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online",
                   errp, "%u", 0);
    if (*errp) {
        goto abort;
    }

    xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state",
                   errp, "%u", XenbusStateClosing);
    if (*errp) {
        goto abort;
    }

    if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
        if (errno == EAGAIN) {
            goto again;
        }

        error_setg_errno(errp, errno, "failed xs_transaction_end");
    }

    return;

abort:
    /*
     * We only abort if there is already a failure so ignore any error
     * from ending the transaction.
     */
    qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
}

static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
{
    XenDevice *xendev = XEN_DEVICE(dev);

    monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
                   indent, "", xendev->name, xendev->frontend_id);
}

static char *xen_bus_get_dev_path(DeviceState *dev)
{
    return xen_device_get_backend_path(XEN_DEVICE(dev));
}

static void xen_bus_backend_create(XenBus *xenbus, const char *type,
                                   const char *name, char *path,
                                   Error **errp)
{
    ERRP_GUARD();
    xs_transaction_t tid;
    char **key;
    QDict *opts;
    unsigned int i, n;

    trace_xen_bus_backend_create(type, path);

again:
    tid = qemu_xen_xs_transaction_start(xenbus->xsh);
    if (tid == XBT_NULL) {
        error_setg(errp, "failed xs_transaction_start");
        return;
    }

    key = qemu_xen_xs_directory(xenbus->xsh, tid, path, &n);
    if (!key) {
        if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, true)) {
            error_setg_errno(errp, errno, "failed xs_transaction_end");
        }
        return;
    }

    opts = qdict_new();
    for (i = 0; i < n; i++) {
        char *val;

        /*
         * Assume anything found in the xenstore backend area, other than
         * the keys created for a generic XenDevice, are parameters
         * to be used to configure the backend.
         */
        if (!strcmp(key[i], "state") ||
            !strcmp(key[i], "online") ||
            !strcmp(key[i], "frontend") ||
            !strcmp(key[i], "frontend-id") ||
            !strcmp(key[i], "hotplug-status"))
            continue;

        if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
                          &val) == 1) {
            qdict_put_str(opts, key[i], val);
            free(val);
        }
    }

    free(key);

    if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
        qobject_unref(opts);

        if (errno == EAGAIN) {
            goto again;
        }

        error_setg_errno(errp, errno, "failed xs_transaction_end");
        return;
    }

    xen_backend_device_create(xenbus, type, name, opts, errp);
    qobject_unref(opts);

    if (*errp) {
        error_prepend(errp, "failed to create '%s' device '%s': ", type, name);
    }
}

static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
{
    char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
    char **backend;
    unsigned int i, n;

    trace_xen_bus_type_enumerate(type);

    backend = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
    if (!backend) {
        goto out;
    }

    for (i = 0; i < n; i++) {
        char *backend_path = g_strdup_printf("%s/%s", domain_path,
                                             backend[i]);
        enum xenbus_state state;
        unsigned int online;

        if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state",
                          NULL, "%u", &state) != 1)
            state = XenbusStateUnknown;

        if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "online",
                          NULL, "%u", &online) != 1)
            online = 0;

        if (online && state == XenbusStateInitialising &&
            !xen_backend_exists(type, backend[i])) {
            Error *local_err = NULL;

            xen_bus_backend_create(xenbus, type, backend[i], backend_path,
                                   &local_err);
            if (local_err) {
                error_report_err(local_err);
            }
        }

        g_free(backend_path);
    }

    free(backend);

out:
    g_free(domain_path);
}

static void xen_bus_enumerate(XenBus *xenbus)
{
    char **type;
    unsigned int i, n;

    trace_xen_bus_enumerate();

    type = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
    if (!type) {
        return;
    }

    for (i = 0; i < n; i++) {
        xen_bus_type_enumerate(xenbus, type[i]);
    }

    free(type);
}

static void xen_bus_device_cleanup(XenDevice *xendev)
{
    const char *type = object_get_typename(OBJECT(xendev));
    Error *local_err = NULL;

    trace_xen_bus_device_cleanup(type, xendev->name);

    g_assert(!xendev->backend_online);

    if (!xen_backend_try_device_destroy(xendev, &local_err)) {
        object_unparent(OBJECT(xendev));
    }

    if (local_err) {
        error_report_err(local_err);
    }
}

static void xen_bus_cleanup(XenBus *xenbus)
{
    XenDevice *xendev, *next;

    trace_xen_bus_cleanup();

    QLIST_FOREACH_SAFE(xendev, &xenbus->inactive_devices, list, next) {
        g_assert(xendev->inactive);
        QLIST_REMOVE(xendev, list);
        xen_bus_device_cleanup(xendev);
    }
}

static void xen_bus_backend_changed(void *opaque, const char *path)
{
    XenBus *xenbus = opaque;

    xen_bus_enumerate(xenbus);
    xen_bus_cleanup(xenbus);
}

static void xen_bus_unrealize(BusState *bus)
{
    XenBus *xenbus = XEN_BUS(bus);

    trace_xen_bus_unrealize();

    if (xenbus->backend_watch) {
        unsigned int i;

        for (i = 0; i < xenbus->backend_types; i++) {
            if (xenbus->backend_watch[i]) {
                xs_node_unwatch(xenbus->xsh, xenbus->backend_watch[i]);
            }
        }

        g_free(xenbus->backend_watch);
        xenbus->backend_watch = NULL;
    }

    if (xenbus->xsh) {
        qemu_xen_xs_close(xenbus->xsh);
    }
}

static void xen_bus_realize(BusState *bus, Error **errp)
{
    char *key = g_strdup_printf("%u", xen_domid);
    XenBus *xenbus = XEN_BUS(bus);
    unsigned int domid;
    const char **type;
    unsigned int i;
    Error *local_err = NULL;

    trace_xen_bus_realize();

    xenbus->xsh = qemu_xen_xs_open();
    if (!xenbus->xsh) {
        error_setg_errno(errp, errno, "failed xs_open");
        goto fail;
    }

    if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */
                      "domid", NULL, "%u", &domid) == 1) {
        xenbus->backend_id = domid;
    } else {
        xenbus->backend_id = 0; /* Assume lack of node means dom0 */
    }

    module_call_init(MODULE_INIT_XEN_BACKEND);

    type = xen_backend_get_types(&xenbus->backend_types);
    xenbus->backend_watch = g_new(struct qemu_xs_watch *,
                                  xenbus->backend_types);

    for (i = 0; i < xenbus->backend_types; i++) {
        char *node = g_strdup_printf("backend/%s", type[i]);

        xenbus->backend_watch[i] =
            xs_node_watch(xenbus->xsh, node, key, xen_bus_backend_changed,
                          xenbus, &local_err);
        if (local_err) {
            /* This need not be treated as a hard error so don't propagate */
            error_reportf_err(local_err,
                              "failed to set up '%s' enumeration watch: ",
                              type[i]);
        }

        g_free(node);
    }

    g_free(type);
    g_free(key);
    return;

fail:
    xen_bus_unrealize(bus);
    g_free(key);
}

static void xen_bus_unplug_request(HotplugHandler *hotplug,
                                   DeviceState *dev,
                                   Error **errp)
{
    XenDevice *xendev = XEN_DEVICE(dev);

    xen_device_unplug(xendev, errp);
}

static void xen_bus_class_init(ObjectClass *class, void *data)
{
    BusClass *bus_class = BUS_CLASS(class);
    HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);

    bus_class->print_dev = xen_bus_print_dev;
    bus_class->get_dev_path = xen_bus_get_dev_path;
    bus_class->realize = xen_bus_realize;
    bus_class->unrealize = xen_bus_unrealize;

    hotplug_class->unplug_request = xen_bus_unplug_request;
}

static const TypeInfo xen_bus_type_info = {
    .name = TYPE_XEN_BUS,
    .parent = TYPE_BUS,
    .instance_size = sizeof(XenBus),
    .class_size = sizeof(XenBusClass),
    .class_init = xen_bus_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_HOTPLUG_HANDLER },
        { }
    },
};

void xen_device_backend_printf(XenDevice *xendev, const char *key,
                               const char *fmt, ...)
{
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    Error *local_err = NULL;
    va_list ap;

    g_assert(xenbus->xsh);

    va_start(ap, fmt);
    xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
                    &local_err, fmt, ap);
    va_end(ap);

    if (local_err) {
        error_report_err(local_err);
    }
}

G_GNUC_SCANF(3, 4)
static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
                                    const char *fmt, ...)
{
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    va_list ap;
    int rc;

    g_assert(xenbus->xsh);

    va_start(ap, fmt);
    rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
                        NULL, fmt, ap);
    va_end(ap);

    return rc;
}

void xen_device_backend_set_state(XenDevice *xendev,
                                  enum xenbus_state state)
{
    const char *type = object_get_typename(OBJECT(xendev));

    if (xendev->backend_state == state) {
        return;
    }

    trace_xen_device_backend_state(type, xendev->name,
                                   xs_strstate(state));

    xendev->backend_state = state;
    xen_device_backend_printf(xendev, "state", "%u", state);
}

enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
{
    return xendev->backend_state;
}

static void xen_device_backend_set_online(XenDevice *xendev, bool online)
{
    const char *type = object_get_typename(OBJECT(xendev));

    if (xendev->backend_online == online) {
        return;
    }

    trace_xen_device_backend_online(type, xendev->name, online);

    xendev->backend_online = online;
    xen_device_backend_printf(xendev, "online", "%u", online);
}

/*
 * Tell from the state whether the frontend is likely alive,
 * i.e. it will react to a change of state of the backend.
 */
static bool xen_device_frontend_is_active(XenDevice *xendev)
{
    switch (xendev->frontend_state) {
    case XenbusStateInitWait:
    case XenbusStateInitialised:
    case XenbusStateConnected:
    case XenbusStateClosing:
        return true;
    default:
        return false;
    }
}

static void xen_device_backend_changed(void *opaque, const char *path)
{
    XenDevice *xendev = opaque;
    const char *type = object_get_typename(OBJECT(xendev));
    enum xenbus_state state;
    unsigned int online;

    trace_xen_device_backend_changed(type, xendev->name);

    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
        state = XenbusStateUnknown;
    }

    xen_device_backend_set_state(xendev, state);

    if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
        online = 0;
    }

    xen_device_backend_set_online(xendev, !!online);

    /*
     * If the toolstack (or unplug request callback) has set the backend
     * state to Closing, but there is no active frontend then set the
     * backend state to Closed.
     */
    if (state == XenbusStateClosing &&
        !xen_device_frontend_is_active(xendev)) {
        xen_device_backend_set_state(xendev, XenbusStateClosed);
    }

    /*
     * If a backend is still 'online' then we should leave it alone but,
     * if a backend is not 'online', then the device is a candidate
     * for destruction. Hence add it to the 'inactive' list to be cleaned
     * by xen_bus_cleanup().
     */
    if (!online &&
        (state == XenbusStateClosed ||  state == XenbusStateInitialising ||
         state == XenbusStateInitWait || state == XenbusStateUnknown) &&
        !xendev->inactive) {
        XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));

        xendev->inactive = true;
        QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list);

        /*
         * Re-write the state to cause a XenBus backend_watch notification,
         * resulting in a call to xen_bus_cleanup().
         */
        xen_device_backend_printf(xendev, "state", "%u", state);
    }
}

static void xen_device_backend_create(XenDevice *xendev, Error **errp)
{
    ERRP_GUARD();
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));

    xendev->backend_path = xen_device_get_backend_path(xendev);

    g_assert(xenbus->xsh);

    xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path,
                   xenbus->backend_id, xendev->frontend_id, XS_PERM_READ, errp);
    if (*errp) {
        error_prepend(errp, "failed to create backend: ");
        return;
    }

    xendev->backend_state_watch =
        xs_node_watch(xendev->xsh, xendev->backend_path,
                      "state", xen_device_backend_changed, xendev,
                      errp);
    if (*errp) {
        error_prepend(errp, "failed to watch backend state: ");
        return;
    }

    xendev->backend_online_watch =
        xs_node_watch(xendev->xsh, xendev->backend_path,
                      "online", xen_device_backend_changed, xendev,
                      errp);
    if (*errp) {
        error_prepend(errp, "failed to watch backend online: ");
        return;
    }
}

static void xen_device_backend_destroy(XenDevice *xendev)
{
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    Error *local_err = NULL;

    if (xendev->backend_online_watch) {
        xs_node_unwatch(xendev->xsh, xendev->backend_online_watch);
        xendev->backend_online_watch = NULL;
    }

    if (xendev->backend_state_watch) {
        xs_node_unwatch(xendev->xsh, xendev->backend_state_watch);
        xendev->backend_state_watch = NULL;
    }

    if (!xendev->backend_path) {
        return;
    }

    g_assert(xenbus->xsh);

    xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path,
                    &local_err);
    g_free(xendev->backend_path);
    xendev->backend_path = NULL;

    if (local_err) {
        error_report_err(local_err);
    }
}

void xen_device_frontend_printf(XenDevice *xendev, const char *key,
                                const char *fmt, ...)
{
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    Error *local_err = NULL;
    va_list ap;

    g_assert(xenbus->xsh);

    va_start(ap, fmt);
    xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
                    &local_err, fmt, ap);
    va_end(ap);

    if (local_err) {
        error_report_err(local_err);
    }
}

int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
                              const char *fmt, ...)
{
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    va_list ap;
    int rc;

    g_assert(xenbus->xsh);

    va_start(ap, fmt);
    rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
                        NULL, fmt, ap);
    va_end(ap);

    return rc;
}

static void xen_device_frontend_set_state(XenDevice *xendev,
                                          enum xenbus_state state,
                                          bool publish)
{
    const char *type = object_get_typename(OBJECT(xendev));

    if (xendev->frontend_state == state) {
        return;
    }

    trace_xen_device_frontend_state(type, xendev->name,
                                    xs_strstate(state));

    xendev->frontend_state = state;
    if (publish) {
        xen_device_frontend_printf(xendev, "state", "%u", state);
    }
}

static void xen_device_frontend_changed(void *opaque, const char *path)
{
    XenDevice *xendev = opaque;
    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
    const char *type = object_get_typename(OBJECT(xendev));
    enum xenbus_state state;

    trace_xen_device_frontend_changed(type, xendev->name);

    if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
        state = XenbusStateUnknown;
    }

    xen_device_frontend_set_state(xendev, state, false);

    if (state == XenbusStateInitialising &&
        xendev->backend_state == XenbusStateClosed &&
        xendev->backend_online) {
        /*
         * The frontend is re-initializing so switch back to
         * InitWait.
         */
        xen_device_backend_set_state(xendev, XenbusStateInitWait);
        return;
    }

    if (xendev_class->frontend_changed) {
        Error *local_err = NULL;

        xendev_class->frontend_changed(xendev, state, &local_err);

        if (local_err) {
            error_reportf_err(local_err, "frontend change error: ");
        }
    }
}

static bool xen_device_frontend_exists(XenDevice *xendev)
{
    enum xenbus_state state;

    return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
}

static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
{
    ERRP_GUARD();
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);

    if (xendev_class->get_frontend_path) {
        xendev->frontend_path = xendev_class->get_frontend_path(xendev, errp);
        if (!xendev->frontend_path) {
            error_prepend(errp, "failed to create frontend: ");
            return;
        }
    } else {
        xendev->frontend_path = xen_device_get_frontend_path(xendev);
    }

    /*
     * The frontend area may have already been created by a legacy
     * toolstack.
     */
    if (!xen_device_frontend_exists(xendev)) {
        g_assert(xenbus->xsh);

        xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path,
                       xendev->frontend_id, xenbus->backend_id,
                       XS_PERM_READ | XS_PERM_WRITE, errp);
        if (*errp) {
            error_prepend(errp, "failed to create frontend: ");
            return;
        }
    }

    xendev->frontend_state_watch =
        xs_node_watch(xendev->xsh, xendev->frontend_path, "state",
                      xen_device_frontend_changed, xendev, errp);
    if (*errp) {
        error_prepend(errp, "failed to watch frontend state: ");
    }
}

static void xen_device_frontend_destroy(XenDevice *xendev)
{
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    Error *local_err = NULL;

    if (xendev->frontend_state_watch) {
        xs_node_unwatch(xendev->xsh, xendev->frontend_state_watch);
        xendev->frontend_state_watch = NULL;
    }

    if (!xendev->frontend_path) {
        return;
    }

    g_assert(xenbus->xsh);

    xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path,
                    &local_err);
    g_free(xendev->frontend_path);
    xendev->frontend_path = NULL;

    if (local_err) {
        error_report_err(local_err);
    }
}

void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
                                   Error **errp)
{
    if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) {
        error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
    }
}

void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
                                unsigned int nr_refs, int prot,
                                Error **errp)
{
    void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs,
                                         xendev->frontend_id, refs, prot);

    if (!map) {
        error_setg_errno(errp, errno,
                         "xengnttab_map_domain_grant_refs failed");
    }

    return map;
}

void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, uint32_t *refs,
                                 unsigned int nr_refs, Error **errp)
{
    if (qemu_xen_gnttab_unmap(xendev->xgth, map, refs, nr_refs)) {
        error_setg_errno(errp, errno, "xengnttab_unmap failed");
    }
}

void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
                                XenDeviceGrantCopySegment segs[],
                                unsigned int nr_segs, Error **errp)
{
    qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id,
                               (XenGrantCopySegment *)segs, nr_segs, errp);
}

struct XenEventChannel {
    QLIST_ENTRY(XenEventChannel) list;
    AioContext *ctx;
    xenevtchn_handle *xeh;
    evtchn_port_t local_port;
    XenEventHandler handler;
    void *opaque;
};

static bool xen_device_poll(void *opaque)
{
    XenEventChannel *channel = opaque;

    return channel->handler(channel->opaque);
}

static void xen_device_event(void *opaque)
{
    XenEventChannel *channel = opaque;
    unsigned long port = qemu_xen_evtchn_pending(channel->xeh);

    if (port == channel->local_port) {
        xen_device_poll(channel);

        qemu_xen_evtchn_unmask(channel->xeh, port);
    }
}

void xen_device_set_event_channel_context(XenDevice *xendev,
                                          XenEventChannel *channel,
                                          AioContext *ctx,
                                          Error **errp)
{
    if (!channel) {
        error_setg(errp, "bad channel");
        return;
    }

    if (channel->ctx)
        aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
                           NULL, NULL, NULL, NULL, NULL);

    channel->ctx = ctx;
    if (ctx) {
        aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
                           xen_device_event, NULL, xen_device_poll, NULL,
                           channel);
    }
}

XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
                                               unsigned int port,
                                               XenEventHandler handler,
                                               void *opaque, Error **errp)
{
    XenEventChannel *channel = g_new0(XenEventChannel, 1);
    xenevtchn_port_or_error_t local_port;

    channel->xeh = qemu_xen_evtchn_open();
    if (!channel->xeh) {
        error_setg_errno(errp, errno, "failed xenevtchn_open");
        goto fail;
    }

    local_port = qemu_xen_evtchn_bind_interdomain(channel->xeh,
                                            xendev->frontend_id,
                                            port);
    if (local_port < 0) {
        error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
        goto fail;
    }

    channel->local_port = local_port;
    channel->handler = handler;
    channel->opaque = opaque;

    /* Only reason for failure is a NULL channel */
    xen_device_set_event_channel_context(xendev, channel,
                                         qemu_get_aio_context(),
                                         &error_abort);

    QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);

    return channel;

fail:
    if (channel->xeh) {
        qemu_xen_evtchn_close(channel->xeh);
    }

    g_free(channel);

    return NULL;
}

void xen_device_notify_event_channel(XenDevice *xendev,
                                     XenEventChannel *channel,
                                     Error **errp)
{
    if (!channel) {
        error_setg(errp, "bad channel");
        return;
    }

    if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) {
        error_setg_errno(errp, errno, "xenevtchn_notify failed");
    }
}

unsigned int xen_event_channel_get_local_port(XenEventChannel *channel)
{
    return channel->local_port;
}

void xen_device_unbind_event_channel(XenDevice *xendev,
                                     XenEventChannel *channel,
                                     Error **errp)
{
    if (!channel) {
        error_setg(errp, "bad channel");
        return;
    }

    QLIST_REMOVE(channel, list);

    if (channel->ctx) {
        aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
                           NULL, NULL, NULL, NULL, NULL);
    }

    if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) {
        error_setg_errno(errp, errno, "xenevtchn_unbind failed");
    }

    qemu_xen_evtchn_close(channel->xeh);
    g_free(channel);
}

static void xen_device_unrealize(DeviceState *dev)
{
    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;
    }

    trace_xen_device_unrealize(type, xendev->name);

    if (xendev->exit.notify) {
        qemu_remove_exit_notifier(&xendev->exit);
        xendev->exit.notify = NULL;
    }

    if (xendev_class->unrealize) {
        xendev_class->unrealize(xendev);
    }

    /* 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->xgth) {
        qemu_xen_gnttab_close(xendev->xgth);
        xendev->xgth = NULL;
    }

    if (xendev->xsh) {
        qemu_xen_xs_close(xendev->xsh);
        xendev->xsh = NULL;
    }

    g_free(xendev->name);
    xendev->name = NULL;
}

static void xen_device_exit(Notifier *n, void *data)
{
    XenDevice *xendev = container_of(n, XenDevice, exit);

    xen_device_unrealize(DEVICE(xendev));
}

static void xen_device_realize(DeviceState *dev, Error **errp)
{
    ERRP_GUARD();
    XenDevice *xendev = XEN_DEVICE(dev);
    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    const char *type = object_get_typename(OBJECT(xendev));

    if (xendev->frontend_id == DOMID_INVALID) {
        xendev->frontend_id = xen_domid;
    }

    if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
        error_setg(errp, "invalid frontend-id");
        goto unrealize;
    }

    if (!xendev_class->get_name) {
        error_setg(errp, "get_name method not implemented");
        goto unrealize;
    }

    xendev->name = xendev_class->get_name(xendev, errp);
    if (*errp) {
        error_prepend(errp, "failed to get device name: ");
        goto unrealize;
    }

    trace_xen_device_realize(type, xendev->name);

    xendev->xsh = qemu_xen_xs_open();
    if (!xendev->xsh) {
        error_setg_errno(errp, errno, "failed xs_open");
        goto unrealize;
    }

    xendev->xgth = qemu_xen_gnttab_open();
    if (!xendev->xgth) {
        error_setg_errno(errp, errno, "failed xengnttab_open");
        goto unrealize;
    }

    xen_device_backend_create(xendev, errp);
    if (*errp) {
        goto unrealize;
    }

    xen_device_frontend_create(xendev, errp);
    if (*errp) {
        goto unrealize;
    }

    xen_device_backend_printf(xendev, "frontend", "%s",
                              xendev->frontend_path);
    xen_device_backend_printf(xendev, "frontend-id", "%u",
                              xendev->frontend_id);
    xen_device_backend_printf(xendev, "hotplug-status", "connected");

    xen_device_backend_set_online(xendev, true);
    xen_device_backend_set_state(xendev, XenbusStateInitWait);

    if (!xen_device_frontend_exists(xendev)) {
        xen_device_frontend_printf(xendev, "backend", "%s",
                                   xendev->backend_path);
        xen_device_frontend_printf(xendev, "backend-id", "%u",
                                   xenbus->backend_id);

        xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
    }

    if (xendev_class->realize) {
        xendev_class->realize(xendev, errp);
        if (*errp) {
            goto unrealize;
        }
    }

    xendev->exit.notify = xen_device_exit;
    qemu_add_exit_notifier(&xendev->exit);
    return;

unrealize:
    xen_device_unrealize(dev);
}

static Property xen_device_props[] = {
    DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
                       DOMID_INVALID),
    DEFINE_PROP_END_OF_LIST()
};

static void xen_device_class_init(ObjectClass *class, void *data)
{
    DeviceClass *dev_class = DEVICE_CLASS(class);

    dev_class->realize = xen_device_realize;
    dev_class->unrealize = xen_device_unrealize;
    device_class_set_props(dev_class, xen_device_props);
    dev_class->bus_type = TYPE_XEN_BUS;
}

static const TypeInfo xen_device_type_info = {
    .name = TYPE_XEN_DEVICE,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(XenDevice),
    .abstract = true,
    .class_size = sizeof(XenDeviceClass),
    .class_init = xen_device_class_init,
};

typedef struct XenBridge {
    SysBusDevice busdev;
} XenBridge;

#define TYPE_XEN_BRIDGE "xen-bridge"

static const TypeInfo xen_bridge_type_info = {
    .name = TYPE_XEN_BRIDGE,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(XenBridge),
};

static void xen_register_types(void)
{
    type_register_static(&xen_bridge_type_info);
    type_register_static(&xen_bus_type_info);
    type_register_static(&xen_device_type_info);
}

type_init(xen_register_types)

void xen_bus_init(void)
{
    DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
    BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);

    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    qbus_set_bus_hotplug_handler(bus);

    qemu_create_nic_bus_devices(bus, TYPE_XEN_DEVICE, "xen-net-device",
                                "xen", "xen-net-device");
}
