/*
 * QEMU Xen emulation: Grant table support
 *
 * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Authors: David Woodhouse <dwmw2@infradead.org>
 *
 * 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/host-utils.h"
#include "qemu/module.h"
#include "qemu/lockable.h"
#include "qemu/main-loop.h"
#include "qapi/error.h"
#include "qom/object.h"
#include "exec/target_page.h"
#include "exec/address-spaces.h"
#include "migration/vmstate.h"

#include "hw/sysbus.h"
#include "hw/xen/xen.h"
#include "hw/xen/xen_backend_ops.h"
#include "xen_overlay.h"
#include "xen_gnttab.h"
#include "xen_primary_console.h"

#include "sysemu/kvm.h"
#include "sysemu/kvm_xen.h"

#include "hw/xen/interface/memory.h"
#include "hw/xen/interface/grant_table.h"

#define TYPE_XEN_GNTTAB "xen-gnttab"
OBJECT_DECLARE_SIMPLE_TYPE(XenGnttabState, XEN_GNTTAB)

#define ENTRIES_PER_FRAME_V1 (XEN_PAGE_SIZE / sizeof(grant_entry_v1_t))

static struct gnttab_backend_ops emu_gnttab_backend_ops;

struct XenGnttabState {
    /*< private >*/
    SysBusDevice busdev;
    /*< public >*/

    QemuMutex gnt_lock;

    uint32_t nr_frames;
    uint32_t max_frames;

    union {
        grant_entry_v1_t *v1;
        /* Theoretically, v2 support could be added here. */
    } entries;

    MemoryRegion gnt_frames;
    MemoryRegion *gnt_aliases;
    uint64_t *gnt_frame_gpas;

    uint8_t *map_track;
};

struct XenGnttabState *xen_gnttab_singleton;

static void xen_gnttab_realize(DeviceState *dev, Error **errp)
{
    XenGnttabState *s = XEN_GNTTAB(dev);
    int i;

    if (xen_mode != XEN_EMULATE) {
        error_setg(errp, "Xen grant table support is for Xen emulation");
        return;
    }
    s->max_frames = kvm_xen_get_gnttab_max_frames();
    memory_region_init_ram(&s->gnt_frames, OBJECT(dev), "xen:grant_table",
                           XEN_PAGE_SIZE * s->max_frames, &error_abort);
    memory_region_set_enabled(&s->gnt_frames, true);
    s->entries.v1 = memory_region_get_ram_ptr(&s->gnt_frames);

    /* Create individual page-sizes aliases for overlays */
    s->gnt_aliases = (void *)g_new0(MemoryRegion, s->max_frames);
    s->gnt_frame_gpas = (void *)g_new(uint64_t, s->max_frames);
    for (i = 0; i < s->max_frames; i++) {
        memory_region_init_alias(&s->gnt_aliases[i], OBJECT(dev),
                                 NULL, &s->gnt_frames,
                                 i * XEN_PAGE_SIZE, XEN_PAGE_SIZE);
        s->gnt_frame_gpas[i] = INVALID_GPA;
    }

    s->nr_frames = 0;
    memset(s->entries.v1, 0, XEN_PAGE_SIZE * s->max_frames);
    s->entries.v1[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access;
    s->entries.v1[GNTTAB_RESERVED_XENSTORE].frame = XEN_SPECIAL_PFN(XENSTORE);

    qemu_mutex_init(&s->gnt_lock);

    xen_gnttab_singleton = s;

    s->map_track = g_new0(uint8_t, s->max_frames * ENTRIES_PER_FRAME_V1);

    xen_gnttab_ops = &emu_gnttab_backend_ops;
}

static int xen_gnttab_post_load(void *opaque, int version_id)
{
    XenGnttabState *s = XEN_GNTTAB(opaque);
    uint32_t i;

    for (i = 0; i < s->nr_frames; i++) {
        if (s->gnt_frame_gpas[i] != INVALID_GPA) {
            xen_overlay_do_map_page(&s->gnt_aliases[i], s->gnt_frame_gpas[i]);
        }
    }
    return 0;
}

static bool xen_gnttab_is_needed(void *opaque)
{
    return xen_mode == XEN_EMULATE;
}

static const VMStateDescription xen_gnttab_vmstate = {
    .name = "xen_gnttab",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = xen_gnttab_is_needed,
    .post_load = xen_gnttab_post_load,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32(nr_frames, XenGnttabState),
        VMSTATE_VARRAY_UINT32(gnt_frame_gpas, XenGnttabState, nr_frames, 0,
                              vmstate_info_uint64, uint64_t),
        VMSTATE_END_OF_LIST()
    }
};

static void xen_gnttab_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = xen_gnttab_realize;
    dc->vmsd = &xen_gnttab_vmstate;
}

static const TypeInfo xen_gnttab_info = {
    .name          = TYPE_XEN_GNTTAB,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(XenGnttabState),
    .class_init    = xen_gnttab_class_init,
};

void xen_gnttab_create(void)
{
    xen_gnttab_singleton = XEN_GNTTAB(sysbus_create_simple(TYPE_XEN_GNTTAB,
                                                           -1, NULL));
}

static void xen_gnttab_register_types(void)
{
    type_register_static(&xen_gnttab_info);
}

type_init(xen_gnttab_register_types)

int xen_gnttab_map_page(uint64_t idx, uint64_t gfn)
{
    XenGnttabState *s = xen_gnttab_singleton;
    uint64_t gpa = gfn << XEN_PAGE_SHIFT;

    if (!s) {
        return -ENOTSUP;
    }

    if (idx >= s->max_frames) {
        return -EINVAL;
    }

    BQL_LOCK_GUARD();
    QEMU_LOCK_GUARD(&s->gnt_lock);

    xen_overlay_do_map_page(&s->gnt_aliases[idx], gpa);

    s->gnt_frame_gpas[idx] = gpa;

    if (s->nr_frames <= idx) {
        s->nr_frames = idx + 1;
    }

    return 0;
}

int xen_gnttab_set_version_op(struct gnttab_set_version *set)
{
    int ret;

    switch (set->version) {
    case 1:
        ret = 0;
        break;

    case 2:
        /* Behave as before set_version was introduced. */
        ret = -ENOSYS;
        break;

    default:
        ret = -EINVAL;
    }

    set->version = 1;
    return ret;
}

int xen_gnttab_get_version_op(struct gnttab_get_version *get)
{
    if (get->dom != DOMID_SELF && get->dom != xen_domid) {
        return -ESRCH;
    }

    get->version = 1;
    return 0;
}

int xen_gnttab_query_size_op(struct gnttab_query_size *size)
{
    XenGnttabState *s = xen_gnttab_singleton;

    if (!s) {
        return -ENOTSUP;
    }

    if (size->dom != DOMID_SELF && size->dom != xen_domid) {
        size->status = GNTST_bad_domain;
        return 0;
    }

    size->status = GNTST_okay;
    size->nr_frames = s->nr_frames;
    size->max_nr_frames = s->max_frames;
    return 0;
}

/* Track per-open refs, to allow close() to clean up. */
struct active_ref {
    MemoryRegionSection mrs;
    void *virtaddr;
    uint32_t refcnt;
    int prot;
};

static void gnt_unref(XenGnttabState *s, grant_ref_t ref,
                      MemoryRegionSection *mrs, int prot)
{
    if (mrs && mrs->mr) {
        if (prot & PROT_WRITE) {
            memory_region_set_dirty(mrs->mr, mrs->offset_within_region,
                                    XEN_PAGE_SIZE);
        }
        memory_region_unref(mrs->mr);
        mrs->mr = NULL;
    }
    assert(s->map_track[ref] != 0);

    if (--s->map_track[ref] == 0) {
        grant_entry_v1_t *gnt_p = &s->entries.v1[ref];
        qatomic_and(&gnt_p->flags, (uint16_t)~(GTF_reading | GTF_writing));
    }
}

static uint64_t gnt_ref(XenGnttabState *s, grant_ref_t ref, int prot)
{
    uint16_t mask = GTF_type_mask | GTF_sub_page;
    grant_entry_v1_t gnt, *gnt_p;
    int retries = 0;

    if (ref >= s->max_frames * ENTRIES_PER_FRAME_V1 ||
        s->map_track[ref] == UINT8_MAX) {
        return INVALID_GPA;
    }

    if (prot & PROT_WRITE) {
        mask |= GTF_readonly;
    }

    gnt_p = &s->entries.v1[ref];

    /*
     * The guest can legitimately be changing the GTF_readonly flag. Allow
     * that, but don't let a malicious guest cause a livelock.
     */
    for (retries = 0; retries < 5; retries++) {
        uint16_t new_flags;

        /* Read the entry before an atomic operation on its flags */
        gnt = *(volatile grant_entry_v1_t *)gnt_p;

        if ((gnt.flags & mask) != GTF_permit_access ||
            gnt.domid != DOMID_QEMU) {
            return INVALID_GPA;
        }

        new_flags = gnt.flags | GTF_reading;
        if (prot & PROT_WRITE) {
            new_flags |= GTF_writing;
        }

        if (qatomic_cmpxchg(&gnt_p->flags, gnt.flags, new_flags) == gnt.flags) {
            return (uint64_t)gnt.frame << XEN_PAGE_SHIFT;
        }
    }

    return INVALID_GPA;
}

struct xengntdev_handle {
    GHashTable *active_maps;
};

static int xen_be_gnttab_set_max_grants(struct xengntdev_handle *xgt,
                                        uint32_t nr_grants)
{
    return 0;
}

static void *xen_be_gnttab_map_refs(struct xengntdev_handle *xgt,
                                    uint32_t count, uint32_t domid,
                                    uint32_t *refs, int prot)
{
    XenGnttabState *s = xen_gnttab_singleton;
    struct active_ref *act;

    if (!s) {
        errno = ENOTSUP;
        return NULL;
    }

    if (domid != xen_domid) {
        errno = EINVAL;
        return NULL;
    }

    if (!count || count > 4096) {
        errno = EINVAL;
        return NULL;
    }

    /*
     * Making a contiguous mapping from potentially discontiguous grant
     * references would be... distinctly non-trivial. We don't support it.
     * Even changing the API to return an array of pointers, one per page,
     * wouldn't be simple to use in PV backends because some structures
     * actually cross page boundaries (e.g. 32-bit blkif_response ring
     * entries are 12 bytes).
     */
    if (count != 1) {
        errno = EINVAL;
        return NULL;
    }

    QEMU_LOCK_GUARD(&s->gnt_lock);

    act = g_hash_table_lookup(xgt->active_maps, GINT_TO_POINTER(refs[0]));
    if (act) {
        if ((prot & PROT_WRITE) && !(act->prot & PROT_WRITE)) {
            if (gnt_ref(s, refs[0], prot) == INVALID_GPA) {
                return NULL;
            }
            act->prot |= PROT_WRITE;
        }
        act->refcnt++;
    } else {
        uint64_t gpa = gnt_ref(s, refs[0], prot);
        if (gpa == INVALID_GPA) {
            errno = EINVAL;
            return NULL;
        }

        act = g_new0(struct active_ref, 1);
        act->prot = prot;
        act->refcnt = 1;
        act->mrs = memory_region_find(get_system_memory(), gpa, XEN_PAGE_SIZE);

        if (act->mrs.mr &&
            !int128_lt(act->mrs.size, int128_make64(XEN_PAGE_SIZE)) &&
            memory_region_get_ram_addr(act->mrs.mr) != RAM_ADDR_INVALID) {
            act->virtaddr = qemu_map_ram_ptr(act->mrs.mr->ram_block,
                                             act->mrs.offset_within_region);
        }
        if (!act->virtaddr) {
            gnt_unref(s, refs[0], &act->mrs, 0);
            g_free(act);
            errno = EINVAL;
            return NULL;
        }

        s->map_track[refs[0]]++;
        g_hash_table_insert(xgt->active_maps, GINT_TO_POINTER(refs[0]), act);
    }

    return act->virtaddr;
}

static gboolean do_unmap(gpointer key, gpointer value, gpointer user_data)
{
    XenGnttabState *s = user_data;
    grant_ref_t gref = GPOINTER_TO_INT(key);
    struct active_ref *act = value;

    gnt_unref(s, gref, &act->mrs, act->prot);
    g_free(act);
    return true;
}

static int xen_be_gnttab_unmap(struct xengntdev_handle *xgt,
                               void *start_address, uint32_t *refs,
                               uint32_t count)
{
    XenGnttabState *s = xen_gnttab_singleton;
    struct active_ref *act;

    if (!s) {
        return -ENOTSUP;
    }

    if (count != 1) {
        return -EINVAL;
    }

    QEMU_LOCK_GUARD(&s->gnt_lock);

    act = g_hash_table_lookup(xgt->active_maps, GINT_TO_POINTER(refs[0]));
    if (!act) {
        return -ENOENT;
    }

    if (act->virtaddr != start_address) {
        return -EINVAL;
    }

    if (!--act->refcnt) {
        do_unmap(GINT_TO_POINTER(refs[0]), act, s);
        g_hash_table_remove(xgt->active_maps, GINT_TO_POINTER(refs[0]));
    }

    return 0;
}

/*
 * This looks a bit like the one for true Xen in xen-operations.c but
 * in emulation we don't support multi-page mappings. And under Xen we
 * *want* the multi-page mappings so we have fewer bounces through the
 * kernel and the hypervisor. So the code paths end up being similar,
 * but different.
 */
static int xen_be_gnttab_copy(struct xengntdev_handle *xgt, bool to_domain,
                              uint32_t domid, XenGrantCopySegment *segs,
                              uint32_t nr_segs, Error **errp)
{
    int prot = to_domain ? PROT_WRITE : PROT_READ;
    unsigned int i;

    for (i = 0; i < nr_segs; i++) {
        XenGrantCopySegment *seg = &segs[i];
        void *page;
        uint32_t ref = to_domain ? seg->dest.foreign.ref :
            seg->source.foreign.ref;

        page = xen_be_gnttab_map_refs(xgt, 1, domid, &ref, prot);
        if (!page) {
            if (errp) {
                error_setg_errno(errp, errno,
                                 "xen_be_gnttab_map_refs failed");
            }
            return -errno;
        }

        if (to_domain) {
            memcpy(page + seg->dest.foreign.offset, seg->source.virt,
                   seg->len);
        } else {
            memcpy(seg->dest.virt, page + seg->source.foreign.offset,
                   seg->len);
        }

        if (xen_be_gnttab_unmap(xgt, page, &ref, 1)) {
            if (errp) {
                error_setg_errno(errp, errno, "xen_be_gnttab_unmap failed");
            }
            return -errno;
        }
    }

    return 0;
}

static struct xengntdev_handle *xen_be_gnttab_open(void)
{
    struct xengntdev_handle *xgt = g_new0(struct xengntdev_handle, 1);

    xgt->active_maps = g_hash_table_new(g_direct_hash, g_direct_equal);
    return xgt;
}

static int xen_be_gnttab_close(struct xengntdev_handle *xgt)
{
    XenGnttabState *s = xen_gnttab_singleton;

    if (!s) {
        return -ENOTSUP;
    }

    g_hash_table_foreach_remove(xgt->active_maps, do_unmap, s);
    g_hash_table_destroy(xgt->active_maps);
    g_free(xgt);
    return 0;
}

static struct gnttab_backend_ops emu_gnttab_backend_ops = {
    .open = xen_be_gnttab_open,
    .close = xen_be_gnttab_close,
    .grant_copy = xen_be_gnttab_copy,
    .set_max_grants = xen_be_gnttab_set_max_grants,
    .map_refs = xen_be_gnttab_map_refs,
    .unmap = xen_be_gnttab_unmap,
};

int xen_gnttab_reset(void)
{
    XenGnttabState *s = xen_gnttab_singleton;

    if (!s) {
        return -ENOTSUP;
    }

    QEMU_LOCK_GUARD(&s->gnt_lock);

    s->nr_frames = 0;

    memset(s->entries.v1, 0, XEN_PAGE_SIZE * s->max_frames);
    s->entries.v1[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access;
    s->entries.v1[GNTTAB_RESERVED_XENSTORE].frame = XEN_SPECIAL_PFN(XENSTORE);

    if (xen_primary_console_get_pfn()) {
        s->entries.v1[GNTTAB_RESERVED_CONSOLE].flags = GTF_permit_access;
        s->entries.v1[GNTTAB_RESERVED_CONSOLE].frame = XEN_SPECIAL_PFN(CONSOLE);
    }

    return 0;
}
