/*
 * 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/cacheinfo.h"
#include "qemu/xxhash.h"
#include "qemu/plugin.h"
#include "qemu/memalign.h"
#include "hw/core/cpu.h"
#include "exec/exec-all.h"
#ifndef CONFIG_USER_ONLY
#include "hw/boards.h"
#endif
#include "qemu/compiler.h"

#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;
    bool is_on;
    char *fullarg;

    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 (arg->curr == NULL) {
            error_setg(errp, "missing earlier '-plugin file=' option");
            return 1;
        }

        if (g_strcmp0(name, "arg") == 0 &&
                !qapi_bool_parse(name, value, &is_on, NULL)) {
            if (strchr(value, '=') == NULL) {
                /* Will treat arg="argname" as "argname=on" */
                fullarg = g_strdup_printf("%s=%s", value, "on");
            } else {
                fullarg = g_strdup_printf("%s", value);
            }
            warn_report("using 'arg=%s' is deprecated", value);
            error_printf("Please use '%s' directly\n", fullarg);
        } else {
            fullarg = g_strdup_printf("%s=%s", name, value);
        }

        p = arg->curr;
        p->argc++;
        p->argv = g_realloc_n(p->argv, p->argc, sizeof(char *));
        p->argv[p->argc - 1] = fullarg;
    }

    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);
}

/*
 * Disable CFI checks.
 * The install and version functions have been loaded from an external library
 * so we do not have type information
 */
QEMU_DISABLE_CFI
static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info, Error **errp)
{
    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_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
        goto err_dlopen;
    }

    if (!g_module_symbol(ctx->handle, "qemu_plugin_install", &sym)) {
        error_setg(errp, "Could not load plugin %s: %s", desc->path, 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_setg(errp, "Could not load plugin %s: qemu_plugin_install is NULL",
                   desc->path);
        goto err_symbol;
    }

    if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) {
        error_setg(errp, "Could not load plugin %s: plugin 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_setg(errp, "Could not load plugin %s: plugin 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_setg(errp, "Could not load plugin %s: plugin 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_setg(errp, "Could not load plugin %s: qemu_plugin_install returned error code %d",
                   desc->path, 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:
    g_module_close(ctx->handle);
 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, Error **errp)
{
    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, errp);
        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);
    }
}
