/*
 * 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->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.shared = g_new0(VhostVDPAShared, 1);
    v->vdpa.shared->device_fd = v->vhostfd;
    v->vdpa.shared->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);
    g_free(v->vdpa.shared);
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);
    g_free(s->vdpa.shared);
    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 = (const 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);
