/*
 * Virtio PMEM device
 *
 * Copyright (C) 2018-2019 Red Hat, Inc.
 *
 * Authors:
 *  Pankaj Gupta <pagupta@redhat.com>
 *  David Hildenbrand <david@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "hw/virtio/virtio-pmem.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio-access.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_pmem.h"
#include "sysemu/hostmem.h"
#include "block/aio.h"
#include "block/thread-pool.h"
#include "trace.h"

typedef struct VirtIODeviceRequest {
    VirtQueueElement elem;
    int fd;
    VirtIOPMEM *pmem;
    VirtIODevice *vdev;
    struct virtio_pmem_req req;
    struct virtio_pmem_resp resp;
} VirtIODeviceRequest;

static int worker_cb(void *opaque)
{
    VirtIODeviceRequest *req_data = opaque;
    int err = 0;

    /* flush raw backing image */
    err = fsync(req_data->fd);
    trace_virtio_pmem_flush_done(err);
    if (err != 0) {
        err = 1;
    }

    virtio_stl_p(req_data->vdev, &req_data->resp.ret, err);

    return 0;
}

static void done_cb(void *opaque, int ret)
{
    VirtIODeviceRequest *req_data = opaque;
    int len = iov_from_buf(req_data->elem.in_sg, req_data->elem.in_num, 0,
                              &req_data->resp, sizeof(struct virtio_pmem_resp));

    /* Callbacks are serialized, so no need to use atomic ops. */
    virtqueue_push(req_data->pmem->rq_vq, &req_data->elem, len);
    virtio_notify((VirtIODevice *)req_data->pmem, req_data->pmem->rq_vq);
    trace_virtio_pmem_response();
    g_free(req_data);
}

static void virtio_pmem_flush(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIODeviceRequest *req_data;
    VirtIOPMEM *pmem = VIRTIO_PMEM(vdev);
    HostMemoryBackend *backend = MEMORY_BACKEND(pmem->memdev);
    ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());

    trace_virtio_pmem_flush_request();
    req_data = virtqueue_pop(vq, sizeof(VirtIODeviceRequest));
    if (!req_data) {
        virtio_error(vdev, "virtio-pmem missing request data");
        return;
    }

    if (req_data->elem.out_num < 1 || req_data->elem.in_num < 1) {
        virtio_error(vdev, "virtio-pmem request not proper");
        virtqueue_detach_element(vq, (VirtQueueElement *)req_data, 0);
        g_free(req_data);
        return;
    }
    req_data->fd   = memory_region_get_fd(&backend->mr);
    req_data->pmem = pmem;
    req_data->vdev = vdev;
    thread_pool_submit_aio(pool, worker_cb, req_data, done_cb, req_data);
}

static void virtio_pmem_get_config(VirtIODevice *vdev, uint8_t *config)
{
    VirtIOPMEM *pmem = VIRTIO_PMEM(vdev);
    struct virtio_pmem_config *pmemcfg = (struct virtio_pmem_config *) config;

    virtio_stq_p(vdev, &pmemcfg->start, pmem->start);
    virtio_stq_p(vdev, &pmemcfg->size, memory_region_size(&pmem->memdev->mr));
}

static uint64_t virtio_pmem_get_features(VirtIODevice *vdev, uint64_t features,
                                        Error **errp)
{
    return features;
}

static void virtio_pmem_realize(DeviceState *dev, Error **errp)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOPMEM *pmem = VIRTIO_PMEM(dev);

    if (!pmem->memdev) {
        error_setg(errp, "virtio-pmem memdev not set");
        return;
    }

    if (host_memory_backend_is_mapped(pmem->memdev)) {
        error_setg(errp, "can't use already busy memdev: %s",
                   object_get_canonical_path_component(OBJECT(pmem->memdev)));
        return;
    }

    host_memory_backend_set_mapped(pmem->memdev, true);
    virtio_init(vdev, VIRTIO_ID_PMEM, sizeof(struct virtio_pmem_config));
    pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush);
}

static void virtio_pmem_unrealize(DeviceState *dev)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOPMEM *pmem = VIRTIO_PMEM(dev);

    host_memory_backend_set_mapped(pmem->memdev, false);
    virtio_delete_queue(pmem->rq_vq);
    virtio_cleanup(vdev);
}

static void virtio_pmem_fill_device_info(const VirtIOPMEM *pmem,
                                         VirtioPMEMDeviceInfo *vi)
{
    vi->memaddr = pmem->start;
    vi->size    = memory_region_size(&pmem->memdev->mr);
    vi->memdev  = object_get_canonical_path(OBJECT(pmem->memdev));
}

static MemoryRegion *virtio_pmem_get_memory_region(VirtIOPMEM *pmem,
                                                   Error **errp)
{
    if (!pmem->memdev) {
        error_setg(errp, "'%s' property must be set", VIRTIO_PMEM_MEMDEV_PROP);
        return NULL;
    }

    return &pmem->memdev->mr;
}

static Property virtio_pmem_properties[] = {
    DEFINE_PROP_UINT64(VIRTIO_PMEM_ADDR_PROP, VirtIOPMEM, start, 0),
    DEFINE_PROP_LINK(VIRTIO_PMEM_MEMDEV_PROP, VirtIOPMEM, memdev,
                     TYPE_MEMORY_BACKEND, HostMemoryBackend *),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_pmem_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
    VirtIOPMEMClass *vpc = VIRTIO_PMEM_CLASS(klass);

    device_class_set_props(dc, virtio_pmem_properties);

    vdc->realize = virtio_pmem_realize;
    vdc->unrealize = virtio_pmem_unrealize;
    vdc->get_config = virtio_pmem_get_config;
    vdc->get_features = virtio_pmem_get_features;

    vpc->fill_device_info = virtio_pmem_fill_device_info;
    vpc->get_memory_region = virtio_pmem_get_memory_region;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo virtio_pmem_info = {
    .name          = TYPE_VIRTIO_PMEM,
    .parent        = TYPE_VIRTIO_DEVICE,
    .class_size    = sizeof(VirtIOPMEMClass),
    .class_init    = virtio_pmem_class_init,
    .instance_size = sizeof(VirtIOPMEM),
};

static void virtio_register_types(void)
{
    type_register_static(&virtio_pmem_info);
}

type_init(virtio_register_types)
