/*
 * QEMU Plugin Core Loader Code
 *
 * This is the code responsible for loading and unloading the plugins.
 * Aside from the basic housekeeping tasks we also need to ensure any
 * generated code is flushed when we remove a plugin so we cannot end
 * up calling and unloaded helper function.
 *
 * Copyright (C) 2017, Emilio G. Cota <cota@braap.org>
 * Copyright (C) 2019, Linaro
 *
 * License: GNU GPL, version 2 or later.
 *   See the COPYING file in the top-level directory.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/config-file.h"
#include "qapi/error.h"
#include "qemu/lockable.h"
#include "qemu/option.h"
#include "qemu/rcu_queue.h"
#include "qemu/qht.h"
#include "qemu/bitmap.h"
#include "qemu/xxhash.h"
#include "qemu/plugin.h"
#include "hw/core/cpu.h"
#include "cpu.h"
#include "exec/exec-all.h"
#ifndef CONFIG_USER_ONLY
#include "hw/boards.h"
#endif

#include "plugin.h"

/*
 * For convenience we use a bitmap for plugin.mask, but really all we need is a
 * u32, which is what we store in TranslationBlock.
 */
QEMU_BUILD_BUG_ON(QEMU_PLUGIN_EV_MAX > 32);

struct qemu_plugin_desc {
    char *path;
    char **argv;
    QTAILQ_ENTRY(qemu_plugin_desc) entry;
    int argc;
};

struct qemu_plugin_parse_arg {
    QemuPluginList *head;
    struct qemu_plugin_desc *curr;
};

QemuOptsList qemu_plugin_opts = {
    .name = "plugin",
    .implied_opt_name = "file",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_plugin_opts.head),
    .desc = {
        /* do our own parsing to support multiple plugins */
        { /* end of list */ }
    },
};

typedef int (*qemu_plugin_install_func_t)(qemu_plugin_id_t, const qemu_info_t *, int, char **);

extern struct qemu_plugin_state plugin;

void qemu_plugin_add_dyn_cb_arr(GArray *arr)
{
    uint32_t hash = qemu_xxhash2((uint64_t)(uintptr_t)arr);
    bool inserted;

    inserted = qht_insert(&plugin.dyn_cb_arr_ht, arr, hash, NULL);
    g_assert(inserted);
}

static struct qemu_plugin_desc *plugin_find_desc(QemuPluginList *head,
                                                 const char *path)
{
    struct qemu_plugin_desc *desc;

    QTAILQ_FOREACH(desc, head, entry) {
        if (strcmp(desc->path, path) == 0) {
            return desc;
        }
    }
    return NULL;
}

static int plugin_add(void *opaque, const char *name, const char *value,
                      Error **errp)
{
    struct qemu_plugin_parse_arg *arg = opaque;
    struct qemu_plugin_desc *p;

    if (strcmp(name, "file") == 0) {
        if (strcmp(value, "") == 0) {
            error_setg(errp, "requires a non-empty argument");
            return 1;
        }
        p = plugin_find_desc(arg->head, value);
        if (p == NULL) {
            p = g_new0(struct qemu_plugin_desc, 1);
            p->path = g_strdup(value);
            QTAILQ_INSERT_TAIL(arg->head, p, entry);
        }
        arg->curr = p;
    } else if (strcmp(name, "arg") == 0) {
        if (arg->curr == NULL) {
            error_setg(errp, "missing earlier '-plugin file=' option");
            return 1;
        }
        p = arg->curr;
        p->argc++;
        p->argv = g_realloc_n(p->argv, p->argc, sizeof(char *));
        p->argv[p->argc - 1] = g_strdup(value);
    } else {
        error_setg(errp, "-plugin: unexpected parameter '%s'; ignored", name);
    }
    return 0;
}

void qemu_plugin_opt_parse(const char *optarg, QemuPluginList *head)
{
    struct qemu_plugin_parse_arg arg;
    QemuOpts *opts;

    opts = qemu_opts_parse_noisily(qemu_find_opts("plugin"), optarg, true);
    if (opts == NULL) {
        exit(1);
    }
    arg.head = head;
    arg.curr = NULL;
    qemu_opt_foreach(opts, plugin_add, &arg, &error_fatal);
    qemu_opts_del(opts);
}

/*
 * From: https://en.wikipedia.org/wiki/Xorshift
 * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
 * guaranteed to be >= INT_MAX).
 */
static uint64_t xorshift64star(uint64_t x)
{
    x ^= x >> 12; /* a */
    x ^= x << 25; /* b */
    x ^= x >> 27; /* c */
    return x * UINT64_C(2685821657736338717);
}

static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
{
    qemu_plugin_install_func_t install;
    struct qemu_plugin_ctx *ctx;
    gpointer sym;
    int rc;

    ctx = qemu_memalign(qemu_dcache_linesize, sizeof(*ctx));
    memset(ctx, 0, sizeof(*ctx));
    ctx->desc = desc;

    ctx->handle = g_module_open(desc->path, G_MODULE_BIND_LOCAL);
    if (ctx->handle == NULL) {
        error_report("%s: %s", __func__, g_module_error());
        goto err_dlopen;
    }

    if (!g_module_symbol(ctx->handle, "qemu_plugin_install", &sym)) {
        error_report("%s: %s", __func__, g_module_error());
        goto err_symbol;
    }
    install = (qemu_plugin_install_func_t) sym;
    /* symbol was found; it could be NULL though */
    if (install == NULL) {
        error_report("%s: %s: qemu_plugin_install is NULL",
                     __func__, desc->path);
        goto err_symbol;
    }

    if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) {
        error_report("TCG plugin %s does not declare API version %s",
                     desc->path, g_module_error());
        goto err_symbol;
    } else {
        int version = *(int *)sym;
        if (version < QEMU_PLUGIN_MIN_VERSION) {
            error_report("TCG plugin %s requires API version %d, but "
                         "this QEMU supports only a minimum version of %d",
                         desc->path, version, QEMU_PLUGIN_MIN_VERSION);
            goto err_symbol;
        } else if (version > QEMU_PLUGIN_VERSION) {
            error_report("TCG plugin %s requires API version %d, but "
                         "this QEMU supports only up to version %d",
                         desc->path, version, QEMU_PLUGIN_VERSION);
            goto err_symbol;
        }
    }

    qemu_rec_mutex_lock(&plugin.lock);

    /* find an unused random id with &ctx as the seed */
    ctx->id = (uint64_t)(uintptr_t)ctx;
    for (;;) {
        void *existing;

        ctx->id = xorshift64star(ctx->id);
        existing = g_hash_table_lookup(plugin.id_ht, &ctx->id);
        if (likely(existing == NULL)) {
            bool success;

            success = g_hash_table_insert(plugin.id_ht, &ctx->id, &ctx->id);
            g_assert(success);
            break;
        }
    }
    QTAILQ_INSERT_TAIL(&plugin.ctxs, ctx, entry);
    ctx->installing = true;
    rc = install(ctx->id, info, desc->argc, desc->argv);
    ctx->installing = false;
    if (rc) {
        error_report("%s: qemu_plugin_install returned error code %d",
                     __func__, rc);
        /*
         * we cannot rely on the plugin doing its own cleanup, so
         * call a full uninstall if the plugin did not yet call it.
         */
        if (!ctx->uninstalling) {
            plugin_reset_uninstall(ctx->id, NULL, false);
        }
    }

    qemu_rec_mutex_unlock(&plugin.lock);
    return rc;

 err_symbol:
 err_dlopen:
    qemu_vfree(ctx);
    return 1;
}

/* call after having removed @desc from the list */
static void plugin_desc_free(struct qemu_plugin_desc *desc)
{
    int i;

    for (i = 0; i < desc->argc; i++) {
        g_free(desc->argv[i]);
    }
    g_free(desc->argv);
    g_free(desc->path);
    g_free(desc);
}

/**
 * qemu_plugin_load_list - load a list of plugins
 * @head: head of the list of descriptors of the plugins to be loaded
 *
 * Returns 0 if all plugins in the list are installed, !0 otherwise.
 *
 * Note: the descriptor of each successfully installed plugin is removed
 * from the list given by @head.
 */
int qemu_plugin_load_list(QemuPluginList *head)
{
    struct qemu_plugin_desc *desc, *next;
    g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);

    info->target_name = TARGET_NAME;
    info->version.min = QEMU_PLUGIN_MIN_VERSION;
    info->version.cur = QEMU_PLUGIN_VERSION;
#ifndef CONFIG_USER_ONLY
    MachineState *ms = MACHINE(qdev_get_machine());
    info->system_emulation = true;
    info->system.smp_vcpus = ms->smp.cpus;
    info->system.max_vcpus = ms->smp.max_cpus;
#else
    info->system_emulation = false;
#endif

    QTAILQ_FOREACH_SAFE(desc, head, entry, next) {
        int err;

        err = plugin_load(desc, info);
        if (err) {
            return err;
        }
        QTAILQ_REMOVE(head, desc, entry);
    }
    return 0;
}

struct qemu_plugin_reset_data {
    struct qemu_plugin_ctx *ctx;
    qemu_plugin_simple_cb_t cb;
    bool reset;
};

static void plugin_reset_destroy__locked(struct qemu_plugin_reset_data *data)
{
    struct qemu_plugin_ctx *ctx = data->ctx;
    enum qemu_plugin_event ev;
    bool success;

    /*
     * After updating the subscription lists there is no need to wait for an RCU
     * grace period to elapse, because right now we either are in a "safe async"
     * work environment (i.e. all vCPUs are asleep), or no vCPUs have yet been
     * created.
     */
    for (ev = 0; ev < QEMU_PLUGIN_EV_MAX; ev++) {
        plugin_unregister_cb__locked(ctx, ev);
    }

    if (data->reset) {
        g_assert(ctx->resetting);
        if (data->cb) {
            data->cb(ctx->id);
        }
        ctx->resetting = false;
        g_free(data);
        return;
    }

    g_assert(ctx->uninstalling);
    /* we cannot dlclose if we are going to return to plugin code */
    if (ctx->installing) {
        error_report("Calling qemu_plugin_uninstall from the install function "
                     "is a bug. Instead, return !0 from the install function.");
        abort();
    }

    success = g_hash_table_remove(plugin.id_ht, &ctx->id);
    g_assert(success);
    QTAILQ_REMOVE(&plugin.ctxs, ctx, entry);
    if (data->cb) {
        data->cb(ctx->id);
    }
    if (!g_module_close(ctx->handle)) {
        warn_report("%s: %s", __func__, g_module_error());
    }
    plugin_desc_free(ctx->desc);
    qemu_vfree(ctx);
    g_free(data);
}

static void plugin_reset_destroy(struct qemu_plugin_reset_data *data)
{
    qemu_rec_mutex_lock(&plugin.lock);
    plugin_reset_destroy__locked(data);
    qemu_rec_mutex_lock(&plugin.lock);
}

static void plugin_flush_destroy(CPUState *cpu, run_on_cpu_data arg)
{
    struct qemu_plugin_reset_data *data = arg.host_ptr;

    g_assert(cpu_in_exclusive_context(cpu));
    tb_flush(cpu);
    plugin_reset_destroy(data);
}

void plugin_reset_uninstall(qemu_plugin_id_t id,
                            qemu_plugin_simple_cb_t cb,
                            bool reset)
{
    struct qemu_plugin_reset_data *data;
    struct qemu_plugin_ctx *ctx;

    WITH_QEMU_LOCK_GUARD(&plugin.lock) {
        ctx = plugin_id_to_ctx_locked(id);
        if (ctx->uninstalling || (reset && ctx->resetting)) {
            return;
        }
        ctx->resetting = reset;
        ctx->uninstalling = !reset;
    }

    data = g_new(struct qemu_plugin_reset_data, 1);
    data->ctx = ctx;
    data->cb = cb;
    data->reset = reset;
    /*
     * Only flush the code cache if the vCPUs have been created. If so,
     * current_cpu must be non-NULL.
     */
    if (current_cpu) {
        async_safe_run_on_cpu(current_cpu, plugin_flush_destroy,
                              RUN_ON_CPU_HOST_PTR(data));
    } else {
        /*
         * If current_cpu isn't set, then we don't have yet any vCPU threads
         * and we therefore can remove the callbacks synchronously.
         */
        plugin_reset_destroy(data);
    }
}
