/*
 * vhost-user GPU Device
 *
 * Copyright Red Hat, Inc. 2018
 *
 * Authors:
 *     Marc-André Lureau <marcandre.lureau@redhat.com>
 *
 * 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/sockets.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio-gpu.h"
#include "chardev/char-fe.h"
#include "qapi/error.h"
#include "migration/blocker.h"
#include "standard-headers/drm/drm_fourcc.h"

typedef enum VhostUserGpuRequest {
    VHOST_USER_GPU_NONE = 0,
    VHOST_USER_GPU_GET_PROTOCOL_FEATURES,
    VHOST_USER_GPU_SET_PROTOCOL_FEATURES,
    VHOST_USER_GPU_GET_DISPLAY_INFO,
    VHOST_USER_GPU_CURSOR_POS,
    VHOST_USER_GPU_CURSOR_POS_HIDE,
    VHOST_USER_GPU_CURSOR_UPDATE,
    VHOST_USER_GPU_SCANOUT,
    VHOST_USER_GPU_UPDATE,
    VHOST_USER_GPU_DMABUF_SCANOUT,
    VHOST_USER_GPU_DMABUF_UPDATE,
    VHOST_USER_GPU_GET_EDID,
    VHOST_USER_GPU_DMABUF_SCANOUT2,
} VhostUserGpuRequest;

typedef struct VhostUserGpuDisplayInfoReply {
    struct virtio_gpu_resp_display_info info;
} VhostUserGpuDisplayInfoReply;

typedef struct VhostUserGpuCursorPos {
    uint32_t scanout_id;
    uint32_t x;
    uint32_t y;
} QEMU_PACKED VhostUserGpuCursorPos;

typedef struct VhostUserGpuCursorUpdate {
    VhostUserGpuCursorPos pos;
    uint32_t hot_x;
    uint32_t hot_y;
    uint32_t data[64 * 64];
} QEMU_PACKED VhostUserGpuCursorUpdate;

typedef struct VhostUserGpuScanout {
    uint32_t scanout_id;
    uint32_t width;
    uint32_t height;
} QEMU_PACKED VhostUserGpuScanout;

typedef struct VhostUserGpuUpdate {
    uint32_t scanout_id;
    uint32_t x;
    uint32_t y;
    uint32_t width;
    uint32_t height;
    uint8_t data[];
} QEMU_PACKED VhostUserGpuUpdate;

typedef struct VhostUserGpuDMABUFScanout {
    uint32_t scanout_id;
    uint32_t x;
    uint32_t y;
    uint32_t width;
    uint32_t height;
    uint32_t fd_width;
    uint32_t fd_height;
    uint32_t fd_stride;
    uint32_t fd_flags;
    int fd_drm_fourcc;
} QEMU_PACKED VhostUserGpuDMABUFScanout;

typedef struct VhostUserGpuDMABUFScanout2 {
    struct VhostUserGpuDMABUFScanout dmabuf_scanout;
    uint64_t modifier;
} QEMU_PACKED VhostUserGpuDMABUFScanout2;

typedef struct VhostUserGpuEdidRequest {
    uint32_t scanout_id;
} QEMU_PACKED VhostUserGpuEdidRequest;

typedef struct VhostUserGpuMsg {
    uint32_t request; /* VhostUserGpuRequest */
    uint32_t flags;
    uint32_t size; /* the following payload size */
    union {
        VhostUserGpuCursorPos cursor_pos;
        VhostUserGpuCursorUpdate cursor_update;
        VhostUserGpuScanout scanout;
        VhostUserGpuUpdate update;
        VhostUserGpuDMABUFScanout dmabuf_scanout;
        VhostUserGpuDMABUFScanout2 dmabuf_scanout2;
        VhostUserGpuEdidRequest edid_req;
        struct virtio_gpu_resp_edid resp_edid;
        struct virtio_gpu_resp_display_info display_info;
        uint64_t u64;
    } payload;
} QEMU_PACKED VhostUserGpuMsg;

static VhostUserGpuMsg m __attribute__ ((unused));
#define VHOST_USER_GPU_HDR_SIZE \
    (sizeof(m.request) + sizeof(m.size) + sizeof(m.flags))

#define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4

#define VHOST_USER_GPU_PROTOCOL_F_EDID 0
#define VHOST_USER_GPU_PROTOCOL_F_DMABUF2 1

static void vhost_user_gpu_update_blocked(VhostUserGPU *g, bool blocked);

static void
vhost_user_gpu_handle_cursor(VhostUserGPU *g, VhostUserGpuMsg *msg)
{
    VhostUserGpuCursorPos *pos = &msg->payload.cursor_pos;
    struct virtio_gpu_scanout *s;

    if (pos->scanout_id >= g->parent_obj.conf.max_outputs) {
        return;
    }
    s = &g->parent_obj.scanout[pos->scanout_id];

    if (msg->request == VHOST_USER_GPU_CURSOR_UPDATE) {
        VhostUserGpuCursorUpdate *up = &msg->payload.cursor_update;
        if (!s->current_cursor) {
            s->current_cursor = cursor_alloc(64, 64);
        }

        s->current_cursor->hot_x = up->hot_x;
        s->current_cursor->hot_y = up->hot_y;

        memcpy(s->current_cursor->data, up->data,
               64 * 64 * sizeof(uint32_t));

        dpy_cursor_define(s->con, s->current_cursor);
    }

    dpy_mouse_set(s->con, pos->x, pos->y,
                  msg->request != VHOST_USER_GPU_CURSOR_POS_HIDE);
}

static void
vhost_user_gpu_send_msg(VhostUserGPU *g, const VhostUserGpuMsg *msg)
{
    qemu_chr_fe_write(&g->vhost_chr, (uint8_t *)msg,
                      VHOST_USER_GPU_HDR_SIZE + msg->size);
}

static void
vhost_user_gpu_unblock(VhostUserGPU *g)
{
    VhostUserGpuMsg msg = {
        .request = VHOST_USER_GPU_DMABUF_UPDATE,
        .flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
    };

    vhost_user_gpu_send_msg(g, &msg);
}

static void
vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)
{
    QemuConsole *con = NULL;
    struct virtio_gpu_scanout *s;

    switch (msg->request) {
    case VHOST_USER_GPU_GET_PROTOCOL_FEATURES: {
        VhostUserGpuMsg reply = {
            .request = msg->request,
            .flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
            .size = sizeof(uint64_t),
            .payload = {
                .u64 = (1 << VHOST_USER_GPU_PROTOCOL_F_EDID) |
                       (1 << VHOST_USER_GPU_PROTOCOL_F_DMABUF2)
            }
        };

        vhost_user_gpu_send_msg(g, &reply);
        break;
    }
    case VHOST_USER_GPU_SET_PROTOCOL_FEATURES: {
        break;
    }
    case VHOST_USER_GPU_GET_DISPLAY_INFO: {
        struct virtio_gpu_resp_display_info display_info = { {} };
        VhostUserGpuMsg reply = {
            .request = msg->request,
            .flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
            .size = sizeof(struct virtio_gpu_resp_display_info),
        };

        display_info.hdr.type = VIRTIO_GPU_RESP_OK_DISPLAY_INFO;
        virtio_gpu_base_fill_display_info(VIRTIO_GPU_BASE(g), &display_info);
        memcpy(&reply.payload.display_info, &display_info,
               sizeof(display_info));
        vhost_user_gpu_send_msg(g, &reply);
        break;
    }
    case VHOST_USER_GPU_GET_EDID: {
        VhostUserGpuEdidRequest *m = &msg->payload.edid_req;
        struct virtio_gpu_resp_edid resp = { {} };
        VhostUserGpuMsg reply = {
            .request = msg->request,
            .flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
            .size = sizeof(reply.payload.resp_edid),
        };

        if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
            error_report("invalid scanout: %d", m->scanout_id);
            break;
        }

        resp.hdr.type = VIRTIO_GPU_RESP_OK_EDID;
        virtio_gpu_base_generate_edid(VIRTIO_GPU_BASE(g), m->scanout_id, &resp);
        memcpy(&reply.payload.resp_edid, &resp, sizeof(resp));
        vhost_user_gpu_send_msg(g, &reply);
        break;
    }
    case VHOST_USER_GPU_SCANOUT: {
        VhostUserGpuScanout *m = &msg->payload.scanout;

        if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
            return;
        }

        g->parent_obj.enable = 1;
        s = &g->parent_obj.scanout[m->scanout_id];
        con = s->con;

        if (m->width == 0) {
            dpy_gfx_replace_surface(con, NULL);
        } else {
            s->ds = qemu_create_displaysurface(m->width, m->height);
            /* replace surface on next update */
        }

        break;
    }
    case VHOST_USER_GPU_DMABUF_SCANOUT2:
    case VHOST_USER_GPU_DMABUF_SCANOUT: {
        VhostUserGpuDMABUFScanout *m = &msg->payload.dmabuf_scanout;
        int fd = qemu_chr_fe_get_msgfd(&g->vhost_chr);
        uint32_t offset = 0;
        uint32_t stride = m->fd_stride;
        uint64_t modifier = DRM_FORMAT_MOD_INVALID;
        QemuDmaBuf *dmabuf;

        if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
            error_report("invalid scanout: %d", m->scanout_id);
            if (fd >= 0) {
                close(fd);
            }
            break;
        }

        g->parent_obj.enable = 1;
        con = g->parent_obj.scanout[m->scanout_id].con;
        dmabuf = g->dmabuf[m->scanout_id];

        if (dmabuf) {
            qemu_dmabuf_close(dmabuf);
            dpy_gl_release_dmabuf(con, dmabuf);
            g_clear_pointer(&dmabuf, qemu_dmabuf_free);
        }

        if (fd == -1) {
            dpy_gl_scanout_disable(con);
            g->dmabuf[m->scanout_id] = NULL;
            break;
        }

        if (msg->request == VHOST_USER_GPU_DMABUF_SCANOUT2) {
            VhostUserGpuDMABUFScanout2 *m2 = &msg->payload.dmabuf_scanout2;
            modifier = m2->modifier;
        }

        dmabuf = qemu_dmabuf_new(m->width, m->height,
                                 &offset, &stride, 0, 0,
                                 m->fd_width, m->fd_height,
                                 m->fd_drm_fourcc, modifier,
                                 &fd, 1, false, m->fd_flags &
                                 VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP);

        dpy_gl_scanout_dmabuf(con, dmabuf);
        g->dmabuf[m->scanout_id] = dmabuf;
        break;
    }
    case VHOST_USER_GPU_DMABUF_UPDATE: {
        VhostUserGpuUpdate *m = &msg->payload.update;

        if (m->scanout_id >= g->parent_obj.conf.max_outputs ||
            !g->parent_obj.scanout[m->scanout_id].con) {
            error_report("invalid scanout update: %d", m->scanout_id);
            vhost_user_gpu_unblock(g);
            break;
        }

        con = g->parent_obj.scanout[m->scanout_id].con;
        if (!console_has_gl(con)) {
            error_report("console doesn't support GL!");
            vhost_user_gpu_unblock(g);
            break;
        }
        g->backend_blocked = true;
        dpy_gl_update(con, m->x, m->y, m->width, m->height);
        break;
    }
#ifdef CONFIG_PIXMAN
    case VHOST_USER_GPU_UPDATE: {
        VhostUserGpuUpdate *m = &msg->payload.update;

        if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
            break;
        }
        s = &g->parent_obj.scanout[m->scanout_id];
        con = s->con;
        pixman_image_t *image =
            pixman_image_create_bits(PIXMAN_x8r8g8b8,
                                     m->width,
                                     m->height,
                                     (uint32_t *)m->data,
                                     m->width * 4);

        pixman_image_composite(PIXMAN_OP_SRC,
                               image, NULL, s->ds->image,
                               0, 0, 0, 0, m->x, m->y, m->width, m->height);

        pixman_image_unref(image);
        if (qemu_console_surface(con) != s->ds) {
            dpy_gfx_replace_surface(con, s->ds);
        } else {
            dpy_gfx_update(con, m->x, m->y, m->width, m->height);
        }
        break;
    }
#endif
    default:
        g_warning("unhandled message %d %d", msg->request, msg->size);
    }

    if (con && qemu_console_is_gl_blocked(con)) {
        vhost_user_gpu_update_blocked(g, true);
    }
}

static void
vhost_user_gpu_chr_read(void *opaque)
{
    VhostUserGPU *g = opaque;
    VhostUserGpuMsg *msg = NULL;
    VhostUserGpuRequest request;
    uint32_t size, flags;
    int r;

    r = qemu_chr_fe_read_all(&g->vhost_chr,
                             (uint8_t *)&request, sizeof(uint32_t));
    if (r != sizeof(uint32_t)) {
        error_report("failed to read msg header: %d, %d", r, errno);
        goto end;
    }

    r = qemu_chr_fe_read_all(&g->vhost_chr,
                             (uint8_t *)&flags, sizeof(uint32_t));
    if (r != sizeof(uint32_t)) {
        error_report("failed to read msg flags");
        goto end;
    }

    r = qemu_chr_fe_read_all(&g->vhost_chr,
                             (uint8_t *)&size, sizeof(uint32_t));
    if (r != sizeof(uint32_t)) {
        error_report("failed to read msg size");
        goto end;
    }

    msg = g_malloc(VHOST_USER_GPU_HDR_SIZE + size);

    r = qemu_chr_fe_read_all(&g->vhost_chr,
                             (uint8_t *)&msg->payload, size);
    if (r != size) {
        error_report("failed to read msg payload %d != %d", r, size);
        goto end;
    }

    msg->request = request;
    msg->flags = flags;
    msg->size = size;

    if (request == VHOST_USER_GPU_CURSOR_UPDATE ||
        request == VHOST_USER_GPU_CURSOR_POS ||
        request == VHOST_USER_GPU_CURSOR_POS_HIDE) {
        vhost_user_gpu_handle_cursor(g, msg);
    } else {
        vhost_user_gpu_handle_display(g, msg);
    }

end:
    g_free(msg);
}

static void
vhost_user_gpu_update_blocked(VhostUserGPU *g, bool blocked)
{
    qemu_set_fd_handler(g->vhost_gpu_fd,
                        blocked ? NULL : vhost_user_gpu_chr_read, NULL, g);
}

static void
vhost_user_gpu_gl_flushed(VirtIOGPUBase *b)
{
    VhostUserGPU *g = VHOST_USER_GPU(b);

    if (g->backend_blocked) {
        vhost_user_gpu_unblock(g);
        g->backend_blocked = false;
    }

    vhost_user_gpu_update_blocked(g, false);
}

static bool
vhost_user_gpu_do_set_socket(VhostUserGPU *g, Error **errp)
{
    Chardev *chr;
    int sv[2];

    if (qemu_socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
        error_setg_errno(errp, errno, "socketpair() failed");
        return false;
    }

    chr = CHARDEV(object_new(TYPE_CHARDEV_SOCKET));
    if (!chr || qemu_chr_add_client(chr, sv[0]) == -1) {
        error_setg(errp, "Failed to make socket chardev");
        goto err;
    }
    if (!qemu_chr_fe_init(&g->vhost_chr, chr, errp)) {
        goto err;
    }
    if (vhost_user_gpu_set_socket(&g->vhost->dev, sv[1]) < 0) {
        error_setg(errp, "Failed to set vhost-user-gpu socket");
        qemu_chr_fe_deinit(&g->vhost_chr, false);
        goto err;
    }

    g->vhost_gpu_fd = sv[0];
    vhost_user_gpu_update_blocked(g, false);
    close(sv[1]);
    return true;

err:
    close(sv[0]);
    close(sv[1]);
    if (chr) {
        object_unref(OBJECT(chr));
    }
    return false;
}

static void
vhost_user_gpu_get_config(VirtIODevice *vdev, uint8_t *config_data)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);
    VirtIOGPUBase *b = VIRTIO_GPU_BASE(vdev);
    struct virtio_gpu_config *vgconfig =
        (struct virtio_gpu_config *)config_data;
    Error *local_err = NULL;
    int ret;

    memset(config_data, 0, sizeof(struct virtio_gpu_config));

    ret = vhost_dev_get_config(&g->vhost->dev,
                               config_data, sizeof(struct virtio_gpu_config),
                               &local_err);
    if (ret) {
        error_report_err(local_err);
        return;
    }

    /* those fields are managed by qemu */
    vgconfig->num_scanouts = b->virtio_config.num_scanouts;
    vgconfig->events_read = b->virtio_config.events_read;
    vgconfig->events_clear = b->virtio_config.events_clear;
}

static void
vhost_user_gpu_set_config(VirtIODevice *vdev,
                          const uint8_t *config_data)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);
    VirtIOGPUBase *b = VIRTIO_GPU_BASE(vdev);
    const struct virtio_gpu_config *vgconfig =
        (const struct virtio_gpu_config *)config_data;
    int ret;

    if (vgconfig->events_clear) {
        b->virtio_config.events_read &= ~vgconfig->events_clear;
    }

    ret = vhost_dev_set_config(&g->vhost->dev, config_data,
                               0, sizeof(struct virtio_gpu_config),
                               VHOST_SET_CONFIG_TYPE_FRONTEND);
    if (ret) {
        error_report("vhost-user-gpu: set device config space failed");
        return;
    }
}

static int
vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);
    Error *err = NULL;

    if (val & VIRTIO_CONFIG_S_DRIVER_OK && vdev->vm_running) {
        if (!vhost_user_gpu_do_set_socket(g, &err)) {
            error_report_err(err);
            return 0;
        }
        vhost_user_backend_start(g->vhost);
    } else {
        int ret;

        /* unblock any wait and stop processing */
        if (g->vhost_gpu_fd != -1) {
            vhost_user_gpu_update_blocked(g, true);
            qemu_chr_fe_deinit(&g->vhost_chr, true);
            g->vhost_gpu_fd = -1;
        }
        ret = vhost_user_backend_stop(g->vhost);
        if (ret < 0) {
            return ret;
        }
    }
    return 0;
}

static bool
vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);

    /*
     * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
     * as the macro of configure interrupt's IDX, If this driver does not
     * support, the function will return
     */

    if (idx == VIRTIO_CONFIG_IRQ_IDX) {
        return false;
    }
    return vhost_virtqueue_pending(&g->vhost->dev, idx);
}

static void
vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);

    /*
     * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
     * as the macro of configure interrupt's IDX, If this driver does not
     * support, the function will return
     */

    if (idx == VIRTIO_CONFIG_IRQ_IDX) {
        return;
    }
    vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask);
}

static void
vhost_user_gpu_instance_init(Object *obj)
{
    VhostUserGPU *g = VHOST_USER_GPU(obj);

    g->vhost = VHOST_USER_BACKEND(object_new(TYPE_VHOST_USER_BACKEND));
    object_property_add_alias(obj, "chardev",
                              OBJECT(g->vhost), "chardev");
}

static void
vhost_user_gpu_instance_finalize(Object *obj)
{
    VhostUserGPU *g = VHOST_USER_GPU(obj);

    object_unref(OBJECT(g->vhost));
}

static void
vhost_user_gpu_reset(VirtIODevice *vdev)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);

    virtio_gpu_base_reset(VIRTIO_GPU_BASE(vdev));

    vhost_user_backend_stop(g->vhost);
}

static int
vhost_user_gpu_config_change(struct vhost_dev *dev)
{
    error_report("vhost-user-gpu: unhandled backend config change");
    return -1;
}

static const VhostDevConfigOps config_ops = {
    .vhost_dev_config_notifier = vhost_user_gpu_config_change,
};

static void
vhost_user_gpu_device_realize(DeviceState *qdev, Error **errp)
{
    VhostUserGPU *g = VHOST_USER_GPU(qdev);
    VirtIODevice *vdev = VIRTIO_DEVICE(g);

    vhost_dev_set_config_notifier(&g->vhost->dev, &config_ops);
    if (vhost_user_backend_dev_init(g->vhost, vdev, 2, errp) < 0) {
        return;
    }

    /* existing backend may send DMABUF, so let's add that requirement */
    g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED;
    if (virtio_has_feature(g->vhost->dev.features, VIRTIO_GPU_F_VIRGL)) {
        g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED;
    }
    if (virtio_has_feature(g->vhost->dev.features, VIRTIO_GPU_F_EDID)) {
        g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_EDID_ENABLED;
    } else {
        error_report("EDID requested but the backend doesn't support it.");
        g->parent_obj.conf.flags &= ~(1 << VIRTIO_GPU_FLAG_EDID_ENABLED);
    }
    if (virtio_has_feature(g->vhost->dev.features,
        VIRTIO_GPU_F_RESOURCE_UUID)) {
        g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_RESOURCE_UUID_ENABLED;
    }
    if (virtio_has_feature(g->vhost->dev.features,
        VIRTIO_GPU_F_RESOURCE_UUID)) {
        g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_RESOURCE_UUID_ENABLED;
    }

    if (!virtio_gpu_base_device_realize(qdev, NULL, NULL, errp)) {
        return;
    }

    g->vhost_gpu_fd = -1;
}

static struct vhost_dev *vhost_user_gpu_get_vhost(VirtIODevice *vdev)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);
    return g->vhost ? &g->vhost->dev : NULL;
}

static const Property vhost_user_gpu_properties[] = {
    VIRTIO_GPU_BASE_PROPERTIES(VhostUserGPU, parent_obj.conf),
};

static void
vhost_user_gpu_class_init(ObjectClass *klass, const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
    VirtIOGPUBaseClass *vgc = VIRTIO_GPU_BASE_CLASS(klass);

    vgc->gl_flushed = vhost_user_gpu_gl_flushed;

    vdc->realize = vhost_user_gpu_device_realize;
    vdc->reset = vhost_user_gpu_reset;
    vdc->set_status   = vhost_user_gpu_set_status;
    vdc->guest_notifier_mask = vhost_user_gpu_guest_notifier_mask;
    vdc->guest_notifier_pending = vhost_user_gpu_guest_notifier_pending;
    vdc->get_config = vhost_user_gpu_get_config;
    vdc->set_config = vhost_user_gpu_set_config;
    vdc->get_vhost = vhost_user_gpu_get_vhost;

    device_class_set_props(dc, vhost_user_gpu_properties);
}

static const TypeInfo vhost_user_gpu_info = {
    .name = TYPE_VHOST_USER_GPU,
    .parent = TYPE_VIRTIO_GPU_BASE,
    .instance_size = sizeof(VhostUserGPU),
    .instance_init = vhost_user_gpu_instance_init,
    .instance_finalize = vhost_user_gpu_instance_finalize,
    .class_init = vhost_user_gpu_class_init,
};
module_obj(TYPE_VHOST_USER_GPU);
module_kconfig(VHOST_USER_GPU);

static void vhost_user_gpu_register_types(void)
{
    type_register_static(&vhost_user_gpu_info);
}

type_init(vhost_user_gpu_register_types)
