/* Copyright 2012 Red Hat, Inc.
 * Copyright IBM, Corp. 2012
 *
 * Based on Linux 2.6.39 vhost code:
 * Copyright (C) 2009 Red Hat, Inc.
 * Copyright (C) 2006 Rusty Russell IBM Corporation
 *
 * Author: Michael S. Tsirkin <mst@redhat.com>
 *         Stefan Hajnoczi <stefanha@redhat.com>
 *
 * Inspiration, some code, and most witty comments come from
 * Documentation/virtual/lguest/lguest.c, by Rusty Russell
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 */

#include "trace.h"
#include "hw/hw.h"
#include "exec/memory.h"
#include "exec/address-spaces.h"
#include "hw/virtio/virtio-access.h"
#include "hw/virtio/dataplane/vring.h"
#include "hw/virtio/dataplane/vring-accessors.h"
#include "qemu/error-report.h"

/* vring_map can be coupled with vring_unmap or (if you still have the
 * value returned in *mr) memory_region_unref.
 */
static void *vring_map(MemoryRegion **mr, hwaddr phys, hwaddr len,
                       bool is_write)
{
    MemoryRegionSection section = memory_region_find(get_system_memory(), phys, len);

    if (!section.mr || int128_get64(section.size) < len) {
        goto out;
    }
    if (is_write && section.readonly) {
        goto out;
    }
    if (!memory_region_is_ram(section.mr)) {
        goto out;
    }

    /* Ignore regions with dirty logging, we cannot mark them dirty */
    if (memory_region_get_dirty_log_mask(section.mr)) {
        goto out;
    }

    *mr = section.mr;
    return memory_region_get_ram_ptr(section.mr) + section.offset_within_region;

out:
    memory_region_unref(section.mr);
    *mr = NULL;
    return NULL;
}

static void vring_unmap(void *buffer, bool is_write)
{
    ram_addr_t addr;
    MemoryRegion *mr;

    mr = qemu_ram_addr_from_host(buffer, &addr);
    memory_region_unref(mr);
}

/* Map the guest's vring to host memory */
bool vring_setup(Vring *vring, VirtIODevice *vdev, int n)
{
    hwaddr vring_addr = virtio_queue_get_ring_addr(vdev, n);
    hwaddr vring_size = virtio_queue_get_ring_size(vdev, n);
    void *vring_ptr;

    vring->broken = false;

    vring_ptr = vring_map(&vring->mr, vring_addr, vring_size, true);
    if (!vring_ptr) {
        error_report("Failed to map vring "
                     "addr %#" HWADDR_PRIx " size %" HWADDR_PRIu,
                     vring_addr, vring_size);
        vring->broken = true;
        return false;
    }

    vring_init(&vring->vr, virtio_queue_get_num(vdev, n), vring_ptr, 4096);

    vring->last_avail_idx = virtio_queue_get_last_avail_idx(vdev, n);
    vring->last_used_idx = vring_get_used_idx(vdev, vring);
    vring->signalled_used = 0;
    vring->signalled_used_valid = false;

    trace_vring_setup(virtio_queue_get_ring_addr(vdev, n),
                      vring->vr.desc, vring->vr.avail, vring->vr.used);
    return true;
}

void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
{
    virtio_queue_set_last_avail_idx(vdev, n, vring->last_avail_idx);
    virtio_queue_invalidate_signalled_used(vdev, n);

    memory_region_unref(vring->mr);
}

/* Disable guest->host notifies */
void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
{
    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
        vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
    }
}

/* Enable guest->host notifies
 *
 * Return true if the vring is empty, false if there are more requests.
 */
bool vring_enable_notification(VirtIODevice *vdev, Vring *vring)
{
    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
        vring_avail_event(&vring->vr) = vring->vr.avail->idx;
    } else {
        vring_clear_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
    }
    smp_mb(); /* ensure update is seen before reading avail_idx */
    return !vring_more_avail(vdev, vring);
}

/* This is stolen from linux/drivers/vhost/vhost.c:vhost_notify() */
bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
{
    uint16_t old, new;
    bool v;
    /* Flush out used index updates. This is paired
     * with the barrier that the Guest executes when enabling
     * interrupts. */
    smp_mb();

    if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
        unlikely(!vring_more_avail(vdev, vring))) {
        return true;
    }

    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
        return !(vring_get_avail_flags(vdev, vring) &
                 VRING_AVAIL_F_NO_INTERRUPT);
    }
    old = vring->signalled_used;
    v = vring->signalled_used_valid;
    new = vring->signalled_used = vring->last_used_idx;
    vring->signalled_used_valid = true;

    if (unlikely(!v)) {
        return true;
    }

    return vring_need_event(vring_used_event(&vring->vr), new, old);
}


static int get_desc(Vring *vring, VirtQueueElement *elem,
                    struct vring_desc *desc)
{
    unsigned *num;
    struct iovec *iov;
    hwaddr *addr;
    MemoryRegion *mr;

    if (desc->flags & VRING_DESC_F_WRITE) {
        num = &elem->in_num;
        iov = &elem->in_sg[*num];
        addr = &elem->in_addr[*num];
    } else {
        num = &elem->out_num;
        iov = &elem->out_sg[*num];
        addr = &elem->out_addr[*num];

        /* If it's an output descriptor, they're all supposed
         * to come before any input descriptors. */
        if (unlikely(elem->in_num)) {
            error_report("Descriptor has out after in");
            return -EFAULT;
        }
    }

    /* Stop for now if there are not enough iovecs available. */
    if (*num >= VIRTQUEUE_MAX_SIZE) {
        error_report("Invalid SG num: %u", *num);
        return -EFAULT;
    }

    /* TODO handle non-contiguous memory across region boundaries */
    iov->iov_base = vring_map(&mr, desc->addr, desc->len,
                              desc->flags & VRING_DESC_F_WRITE);
    if (!iov->iov_base) {
        error_report("Failed to map descriptor addr %#" PRIx64 " len %u",
                     (uint64_t)desc->addr, desc->len);
        return -EFAULT;
    }

    /* The MemoryRegion is looked up again and unref'ed later, leave the
     * ref in place.  */
    iov->iov_len = desc->len;
    *addr = desc->addr;
    *num += 1;
    return 0;
}

static void copy_in_vring_desc(VirtIODevice *vdev,
                               const struct vring_desc *guest,
                               struct vring_desc *host)
{
    host->addr = virtio_ldq_p(vdev, &guest->addr);
    host->len = virtio_ldl_p(vdev, &guest->len);
    host->flags = virtio_lduw_p(vdev, &guest->flags);
    host->next = virtio_lduw_p(vdev, &guest->next);
}

/* This is stolen from linux/drivers/vhost/vhost.c. */
static int get_indirect(VirtIODevice *vdev, Vring *vring,
                        VirtQueueElement *elem, struct vring_desc *indirect)
{
    struct vring_desc desc;
    unsigned int i = 0, count, found = 0;
    int ret;

    /* Sanity check */
    if (unlikely(indirect->len % sizeof(desc))) {
        error_report("Invalid length in indirect descriptor: "
                     "len %#x not multiple of %#zx",
                     indirect->len, sizeof(desc));
        vring->broken = true;
        return -EFAULT;
    }

    count = indirect->len / sizeof(desc);
    /* Buffers are chained via a 16 bit next field, so
     * we can have at most 2^16 of these. */
    if (unlikely(count > USHRT_MAX + 1)) {
        error_report("Indirect buffer length too big: %d", indirect->len);
        vring->broken = true;
        return -EFAULT;
    }

    do {
        struct vring_desc *desc_ptr;
        MemoryRegion *mr;

        /* Translate indirect descriptor */
        desc_ptr = vring_map(&mr,
                             indirect->addr + found * sizeof(desc),
                             sizeof(desc), false);
        if (!desc_ptr) {
            error_report("Failed to map indirect descriptor "
                         "addr %#" PRIx64 " len %zu",
                         (uint64_t)indirect->addr + found * sizeof(desc),
                         sizeof(desc));
            vring->broken = true;
            return -EFAULT;
        }
        copy_in_vring_desc(vdev, desc_ptr, &desc);
        memory_region_unref(mr);

        /* Ensure descriptor has been loaded before accessing fields */
        barrier(); /* read_barrier_depends(); */

        if (unlikely(++found > count)) {
            error_report("Loop detected: last one at %u "
                         "indirect size %u", i, count);
            vring->broken = true;
            return -EFAULT;
        }

        if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) {
            error_report("Nested indirect descriptor");
            vring->broken = true;
            return -EFAULT;
        }

        ret = get_desc(vring, elem, &desc);
        if (ret < 0) {
            vring->broken |= (ret == -EFAULT);
            return ret;
        }
        i = desc.next;
    } while (desc.flags & VRING_DESC_F_NEXT);
    return 0;
}

static void vring_unmap_element(VirtQueueElement *elem)
{
    int i;

    /* This assumes that the iovecs, if changed, are never moved past
     * the end of the valid area.  This is true if iovec manipulations
     * are done with iov_discard_front and iov_discard_back.
     */
    for (i = 0; i < elem->out_num; i++) {
        vring_unmap(elem->out_sg[i].iov_base, false);
    }

    for (i = 0; i < elem->in_num; i++) {
        vring_unmap(elem->in_sg[i].iov_base, true);
    }
}

/* This looks in the virtqueue and for the first available buffer, and converts
 * it to an iovec for convenient access.  Since descriptors consist of some
 * number of output then some number of input descriptors, it's actually two
 * iovecs, but we pack them into one and note how many of each there were.
 *
 * This function returns the descriptor number found, or vq->num (which is
 * never a valid descriptor number) if none was found.  A negative code is
 * returned on error.
 *
 * Stolen from linux/drivers/vhost/vhost.c.
 */
int vring_pop(VirtIODevice *vdev, Vring *vring,
              VirtQueueElement *elem)
{
    struct vring_desc desc;
    unsigned int i, head, found = 0, num = vring->vr.num;
    uint16_t avail_idx, last_avail_idx;
    int ret;

    /* Initialize elem so it can be safely unmapped */
    elem->in_num = elem->out_num = 0;

    /* If there was a fatal error then refuse operation */
    if (vring->broken) {
        ret = -EFAULT;
        goto out;
    }

    /* Check it isn't doing very strange things with descriptor numbers. */
    last_avail_idx = vring->last_avail_idx;
    avail_idx = vring_get_avail_idx(vdev, vring);
    barrier(); /* load indices now and not again later */

    if (unlikely((uint16_t)(avail_idx - last_avail_idx) > num)) {
        error_report("Guest moved used index from %u to %u",
                     last_avail_idx, avail_idx);
        ret = -EFAULT;
        goto out;
    }

    /* If there's nothing new since last we looked. */
    if (avail_idx == last_avail_idx) {
        ret = -EAGAIN;
        goto out;
    }

    /* Only get avail ring entries after they have been exposed by guest. */
    smp_rmb();

    /* Grab the next descriptor number they're advertising, and increment
     * the index we've seen. */
    head = vring_get_avail_ring(vdev, vring, last_avail_idx % num);

    elem->index = head;

    /* If their number is silly, that's an error. */
    if (unlikely(head >= num)) {
        error_report("Guest says index %u > %u is available", head, num);
        ret = -EFAULT;
        goto out;
    }

    i = head;
    do {
        if (unlikely(i >= num)) {
            error_report("Desc index is %u > %u, head = %u", i, num, head);
            ret = -EFAULT;
            goto out;
        }
        if (unlikely(++found > num)) {
            error_report("Loop detected: last one at %u vq size %u head %u",
                         i, num, head);
            ret = -EFAULT;
            goto out;
        }
        copy_in_vring_desc(vdev, &vring->vr.desc[i], &desc);

        /* Ensure descriptor is loaded before accessing fields */
        barrier();

        if (desc.flags & VRING_DESC_F_INDIRECT) {
            ret = get_indirect(vdev, vring, elem, &desc);
            if (ret < 0) {
                goto out;
            }
            continue;
        }

        ret = get_desc(vring, elem, &desc);
        if (ret < 0) {
            goto out;
        }

        i = desc.next;
    } while (desc.flags & VRING_DESC_F_NEXT);

    /* On success, increment avail index. */
    vring->last_avail_idx++;
    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
        vring_avail_event(&vring->vr) = vring->last_avail_idx;
    }

    return head;

out:
    assert(ret < 0);
    if (ret == -EFAULT) {
        vring->broken = true;
    }
    vring_unmap_element(elem);
    return ret;
}

/* After we've used one of their buffers, we tell them about it.
 *
 * Stolen from linux/drivers/vhost/vhost.c.
 */
void vring_push(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
                int len)
{
    unsigned int head = elem->index;
    uint16_t new;

    vring_unmap_element(elem);

    /* Don't touch vring if a fatal error occurred */
    if (vring->broken) {
        return;
    }

    /* The virtqueue contains a ring of used buffers.  Get a pointer to the
     * next entry in that used ring. */
    vring_set_used_ring_id(vdev, vring, vring->last_used_idx % vring->vr.num,
                           head);
    vring_set_used_ring_len(vdev, vring, vring->last_used_idx % vring->vr.num,
                            len);

    /* Make sure buffer is written before we update index. */
    smp_wmb();

    new = ++vring->last_used_idx;
    vring_set_used_idx(vdev, vring, new);
    if (unlikely((int16_t)(new - vring->signalled_used) < (uint16_t)1)) {
        vring->signalled_used_valid = false;
    }
}
