/*
 * Vhost Vdpa Device
 *
 * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved.
 *
 * Authors:
 *   Longpeng <longpeng2@huawei.com>
 *
 * Largely based on the "vhost-user-blk-pci.c" and "vhost-user-blk.c"
 * implemented by:
 *   Changpeng Liu <changpeng.liu@intel.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
 * See the COPYING.LIB file in the top-level directory.
 */
#include "qemu/osdep.h"
#include <sys/ioctl.h>
#include <linux/vhost.h>
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/virtio/vhost.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/vdpa-dev.h"
#include "sysemu/sysemu.h"
#include "sysemu/runstate.h"

static void
vhost_vdpa_device_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
    /* Nothing to do */
}

static uint32_t
vhost_vdpa_device_get_u32(int fd, unsigned long int cmd, Error **errp)
{
    uint32_t val = (uint32_t)-1;

    if (ioctl(fd, cmd, &val) < 0) {
        error_setg(errp, "vhost-vdpa-device: cmd 0x%lx failed: %s",
                   cmd, strerror(errno));
    }

    return val;
}

static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VhostVdpaDevice *v = VHOST_VDPA_DEVICE(vdev);
    struct vhost_vdpa_iova_range iova_range;
    uint16_t max_queue_size;
    struct vhost_virtqueue *vqs;
    int i, ret;

    if (!v->vhostdev) {
        error_setg(errp, "vhost-vdpa-device: vhostdev are missing");
        return;
    }

    v->vhostfd = qemu_open(v->vhostdev, O_RDWR, errp);
    if (*errp) {
        return;
    }
    v->vdpa.device_fd = v->vhostfd;

    v->vdev_id = vhost_vdpa_device_get_u32(v->vhostfd,
                                           VHOST_VDPA_GET_DEVICE_ID, errp);
    if (*errp) {
        goto out;
    }

    max_queue_size = vhost_vdpa_device_get_u32(v->vhostfd,
                                               VHOST_VDPA_GET_VRING_NUM, errp);
    if (*errp) {
        goto out;
    }

    if (v->queue_size > max_queue_size) {
        error_setg(errp, "vhost-vdpa-device: invalid queue_size: %u (max:%u)",
                   v->queue_size, max_queue_size);
        goto out;
    } else if (!v->queue_size) {
        v->queue_size = max_queue_size;
    }

    v->num_queues = vhost_vdpa_device_get_u32(v->vhostfd,
                                              VHOST_VDPA_GET_VQS_COUNT, errp);
    if (*errp) {
        goto out;
    }

    if (!v->num_queues || v->num_queues > VIRTIO_QUEUE_MAX) {
        error_setg(errp, "invalid number of virtqueues: %u (max:%u)",
                   v->num_queues, VIRTIO_QUEUE_MAX);
        goto out;
    }

    v->dev.nvqs = v->num_queues;
    vqs = g_new0(struct vhost_virtqueue, v->dev.nvqs);
    v->dev.vqs = vqs;
    v->dev.vq_index = 0;
    v->dev.vq_index_end = v->dev.nvqs;
    v->dev.backend_features = 0;
    v->started = false;

    ret = vhost_vdpa_get_iova_range(v->vhostfd, &iova_range);
    if (ret < 0) {
        error_setg(errp, "vhost-vdpa-device: get iova range failed: %s",
                   strerror(-ret));
        goto free_vqs;
    }
    v->vdpa.iova_range = iova_range;

    ret = vhost_dev_init(&v->dev, &v->vdpa, VHOST_BACKEND_TYPE_VDPA, 0, NULL);
    if (ret < 0) {
        error_setg(errp, "vhost-vdpa-device: vhost initialization failed: %s",
                   strerror(-ret));
        goto free_vqs;
    }

    v->config_size = vhost_vdpa_device_get_u32(v->vhostfd,
                                               VHOST_VDPA_GET_CONFIG_SIZE,
                                               errp);
    if (*errp) {
        goto vhost_cleanup;
    }

    /*
     * Invoke .post_init() to initialize the transport-specific fields
     * before calling virtio_init().
     */
    if (v->post_init && v->post_init(v, errp) < 0) {
        goto vhost_cleanup;
    }

    v->config = g_malloc0(v->config_size);

    ret = vhost_dev_get_config(&v->dev, v->config, v->config_size, NULL);
    if (ret < 0) {
        error_setg(errp, "vhost-vdpa-device: get config failed");
        goto free_config;
    }

    virtio_init(vdev, v->vdev_id, v->config_size);

    v->virtqs = g_new0(VirtQueue *, v->dev.nvqs);
    for (i = 0; i < v->dev.nvqs; i++) {
        v->virtqs[i] = virtio_add_queue(vdev, v->queue_size,
                                        vhost_vdpa_device_dummy_handle_output);
    }

    return;

free_config:
    g_free(v->config);
vhost_cleanup:
    vhost_dev_cleanup(&v->dev);
free_vqs:
    g_free(vqs);
out:
    qemu_close(v->vhostfd);
    v->vhostfd = -1;
}

static void vhost_vdpa_device_unrealize(DeviceState *dev)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
    int i;

    virtio_set_status(vdev, 0);

    for (i = 0; i < s->num_queues; i++) {
        virtio_delete_queue(s->virtqs[i]);
    }
    g_free(s->virtqs);
    virtio_cleanup(vdev);

    g_free(s->config);
    g_free(s->dev.vqs);
    vhost_dev_cleanup(&s->dev);
    qemu_close(s->vhostfd);
    s->vhostfd = -1;
}

static void
vhost_vdpa_device_get_config(VirtIODevice *vdev, uint8_t *config)
{
    VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);

    memcpy(config, s->config, s->config_size);
}

static void
vhost_vdpa_device_set_config(VirtIODevice *vdev, const uint8_t *config)
{
    VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
    int ret;

    ret = vhost_dev_set_config(&s->dev, s->config, 0, s->config_size,
                               VHOST_SET_CONFIG_TYPE_FRONTEND);
    if (ret) {
        error_report("set device config space failed");
        return;
    }
}

static uint64_t vhost_vdpa_device_get_features(VirtIODevice *vdev,
                                               uint64_t features,
                                               Error **errp)
{
    VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
    uint64_t backend_features = s->dev.features;

    if (!virtio_has_feature(features, VIRTIO_F_IOMMU_PLATFORM)) {
        virtio_clear_feature(&backend_features, VIRTIO_F_IOMMU_PLATFORM);
    }

    return backend_features;
}

static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp)
{
    VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
    int i, ret;

    if (!k->set_guest_notifiers) {
        error_setg(errp, "binding does not support guest notifiers");
        return -ENOSYS;
    }

    ret = vhost_dev_enable_notifiers(&s->dev, vdev);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Error enabling host notifiers");
        return ret;
    }

    ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, true);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Error binding guest notifier");
        goto err_host_notifiers;
    }

    s->dev.acked_features = vdev->guest_features;

    ret = vhost_dev_start(&s->dev, vdev, false);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Error starting vhost");
        goto err_guest_notifiers;
    }
    for (i = 0; i < s->dev.nvqs; ++i) {
        vhost_vdpa_set_vring_ready(&s->vdpa, i);
    }
    s->started = true;

    /*
     * guest_notifier_mask/pending not used yet, so just unmask
     * everything here. virtio-pci will do the right thing by
     * enabling/disabling irqfd.
     */
    for (i = 0; i < s->dev.nvqs; i++) {
        vhost_virtqueue_mask(&s->dev, vdev, i, false);
    }

    return ret;

err_guest_notifiers:
    k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
err_host_notifiers:
    vhost_dev_disable_notifiers(&s->dev, vdev);
    return ret;
}

static void vhost_vdpa_device_stop(VirtIODevice *vdev)
{
    VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
    int ret;

    if (!s->started) {
        return;
    }
    s->started = false;

    if (!k->set_guest_notifiers) {
        return;
    }

    vhost_dev_stop(&s->dev, vdev, false);

    ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
    if (ret < 0) {
        error_report("vhost guest notifier cleanup failed: %d", ret);
        return;
    }

    vhost_dev_disable_notifiers(&s->dev, vdev);
}

static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status)
{
    VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
    bool should_start = virtio_device_started(vdev, status);
    Error *local_err = NULL;
    int ret;

    if (!vdev->vm_running) {
        should_start = false;
    }

    if (s->started == should_start) {
        return;
    }

    if (should_start) {
        ret = vhost_vdpa_device_start(vdev, &local_err);
        if (ret < 0) {
            error_reportf_err(local_err, "vhost-vdpa-device: start failed: ");
        }
    } else {
        vhost_vdpa_device_stop(vdev);
    }
}

static Property vhost_vdpa_device_properties[] = {
    DEFINE_PROP_STRING("vhostdev", VhostVdpaDevice, vhostdev),
    DEFINE_PROP_UINT16("queue-size", VhostVdpaDevice, queue_size, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription vmstate_vhost_vdpa_device = {
    .name = "vhost-vdpa-device",
    .unmigratable = 1,
    .minimum_version_id = 1,
    .version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_VIRTIO_DEVICE,
        VMSTATE_END_OF_LIST()
    },
};

static void vhost_vdpa_device_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    device_class_set_props(dc, vhost_vdpa_device_properties);
    dc->desc = "VDPA-based generic device assignment";
    dc->vmsd = &vmstate_vhost_vdpa_device;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    vdc->realize = vhost_vdpa_device_realize;
    vdc->unrealize = vhost_vdpa_device_unrealize;
    vdc->get_config = vhost_vdpa_device_get_config;
    vdc->set_config = vhost_vdpa_device_set_config;
    vdc->get_features = vhost_vdpa_device_get_features;
    vdc->set_status = vhost_vdpa_device_set_status;
}

static void vhost_vdpa_device_instance_init(Object *obj)
{
    VhostVdpaDevice *s = VHOST_VDPA_DEVICE(obj);

    device_add_bootindex_property(obj, &s->bootindex, "bootindex",
                                  NULL, DEVICE(obj));
}

static const TypeInfo vhost_vdpa_device_info = {
    .name = TYPE_VHOST_VDPA_DEVICE,
    .parent = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(VhostVdpaDevice),
    .class_init = vhost_vdpa_device_class_init,
    .instance_init = vhost_vdpa_device_instance_init,
};

static void register_vhost_vdpa_device_type(void)
{
    type_register_static(&vhost_vdpa_device_info);
}

type_init(register_vhost_vdpa_device_type);
