/*
 * s390 storage attributes device
 *
 * Copyright 2016 IBM Corp.
 * Author(s): Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
 * your option) any later version. See the COPYING file in the top-level
 * directory.
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "migration/qemu-file.h"
#include "migration/register.h"
#include "hw/qdev-properties.h"
#include "hw/s390x/storage-attributes.h"
#include "qemu/error-report.h"
#include "exec/ram_addr.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"

/* 512KiB cover 2GB of guest memory */
#define CMMA_BLOCK_SIZE  (512 * KiB)

#define STATTR_FLAG_EOS     0x01ULL
#define STATTR_FLAG_MORE    0x02ULL
#define STATTR_FLAG_ERROR   0x04ULL
#define STATTR_FLAG_DONE    0x08ULL

static S390StAttribState *s390_get_stattrib_device(void)
{
    S390StAttribState *sas;

    sas = S390_STATTRIB(object_resolve_path_type("", TYPE_S390_STATTRIB, NULL));
    assert(sas);
    return sas;
}

void s390_stattrib_init(void)
{
    Object *obj;

    obj = kvm_s390_stattrib_create();
    if (!obj) {
        obj = object_new(TYPE_QEMU_S390_STATTRIB);
    }

    object_property_add_child(qdev_get_machine(), TYPE_S390_STATTRIB,
                              obj);
    object_unref(obj);

    qdev_realize(DEVICE(obj), NULL, &error_fatal);
}

/* Console commands: */

void hmp_migrationmode(Monitor *mon, const QDict *qdict)
{
    S390StAttribState *sas = s390_get_stattrib_device();
    S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
    uint64_t what = qdict_get_int(qdict, "mode");
    Error *local_err = NULL;
    int r;

    r = sac->set_migrationmode(sas, what, &local_err);
    if (r < 0) {
        monitor_printf(mon, "Error: %s", error_get_pretty(local_err));
        error_free(local_err);
    }
}

void hmp_info_cmma(Monitor *mon, const QDict *qdict)
{
    S390StAttribState *sas = s390_get_stattrib_device();
    S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
    uint64_t addr = qdict_get_int(qdict, "addr");
    uint64_t buflen = qdict_get_try_int(qdict, "count", 8);
    uint8_t *vals;
    int cx, len;

    vals = g_try_malloc(buflen);
    if (!vals) {
        monitor_printf(mon, "Error: %s\n", strerror(errno));
        return;
    }

    len = sac->peek_stattr(sas, addr / TARGET_PAGE_SIZE, buflen, vals);
    if (len < 0) {
        monitor_printf(mon, "Error: %s", strerror(-len));
        goto out;
    }

    monitor_printf(mon, "  CMMA attributes, "
                   "pages %" PRIu64 "+%d (0x%" PRIx64 "):\n",
                   addr / TARGET_PAGE_SIZE, len, addr & ~TARGET_PAGE_MASK);
    for (cx = 0; cx < len; cx++) {
        if (cx % 8 == 7) {
            monitor_printf(mon, "%02x\n", vals[cx]);
        } else {
            monitor_printf(mon, "%02x", vals[cx]);
        }
    }
    monitor_printf(mon, "\n");

out:
    g_free(vals);
}

/* Migration support: */

static int cmma_load(QEMUFile *f, void *opaque, int version_id)
{
    S390StAttribState *sas = S390_STATTRIB(opaque);
    S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
    uint64_t count, cur_gfn;
    int flags, ret = 0;
    ram_addr_t addr;
    uint8_t *buf;

    while (!ret) {
        addr = qemu_get_be64(f);
        flags = addr & ~TARGET_PAGE_MASK;
        addr &= TARGET_PAGE_MASK;

        switch (flags) {
        case STATTR_FLAG_MORE: {
            cur_gfn = addr / TARGET_PAGE_SIZE;
            count = qemu_get_be64(f);
            buf = g_try_malloc(count);
            if (!buf) {
                error_report("cmma_load could not allocate memory");
                ret = -ENOMEM;
                break;
            }

            qemu_get_buffer(f, buf, count);
            ret = sac->set_stattr(sas, cur_gfn, count, buf);
            if (ret < 0) {
                error_report("Error %d while setting storage attributes", ret);
            }
            g_free(buf);
            break;
        }
        case STATTR_FLAG_ERROR: {
            error_report("Storage attributes data is incomplete");
            ret = -EINVAL;
            break;
        }
        case STATTR_FLAG_DONE:
            /* This is after the last pre-copied value has been sent, nothing
             * more will be sent after this. Pre-copy has finished, and we
             * are done flushing all the remaining values. Now the target
             * system is about to take over. We synchronize the buffer to
             * apply the actual correct values where needed.
             */
             sac->synchronize(sas);
            break;
        case STATTR_FLAG_EOS:
            /* Normal exit */
            return 0;
        default:
            error_report("Unexpected storage attribute flag data: %#x", flags);
            ret = -EINVAL;
        }
    }

    return ret;
}

static int cmma_save_setup(QEMUFile *f, void *opaque)
{
    S390StAttribState *sas = S390_STATTRIB(opaque);
    S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
    Error *local_err = NULL;
    int res;
    /*
     * Signal that we want to start a migration, thus needing PGSTE dirty
     * tracking.
     */
    res = sac->set_migrationmode(sas, true, &local_err);
    if (res) {
        error_report_err(local_err);
        return res;
    }
    qemu_put_be64(f, STATTR_FLAG_EOS);
    return 0;
}

static void cmma_state_pending(void *opaque, uint64_t *must_precopy,
                               uint64_t *can_postcopy)
{
    S390StAttribState *sas = S390_STATTRIB(opaque);
    S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
    long long res = sac->get_dirtycount(sas);

    if (res >= 0) {
        *must_precopy += res;
    }
}

static int cmma_save(QEMUFile *f, void *opaque, int final)
{
    S390StAttribState *sas = S390_STATTRIB(opaque);
    S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
    uint8_t *buf;
    int r, cx, reallen = 0, ret = 0;
    uint32_t buflen = CMMA_BLOCK_SIZE;
    uint64_t start_gfn = sas->migration_cur_gfn;

    buf = g_try_malloc(buflen);
    if (!buf) {
        error_report("Could not allocate memory to save storage attributes");
        return -ENOMEM;
    }

    while (final ? 1 : migration_rate_exceeded(f) == 0) {
        reallen = sac->get_stattr(sas, &start_gfn, buflen, buf);
        if (reallen < 0) {
            g_free(buf);
            return reallen;
        }

        ret = 1;
        if (!reallen) {
            break;
        }
        qemu_put_be64(f, (start_gfn << TARGET_PAGE_BITS) | STATTR_FLAG_MORE);
        qemu_put_be64(f, reallen);
        for (cx = 0; cx < reallen; cx++) {
            qemu_put_byte(f, buf[cx]);
        }
        if (!sac->get_dirtycount(sas)) {
            break;
        }
    }

    sas->migration_cur_gfn = start_gfn + reallen;
    g_free(buf);
    if (final) {
        qemu_put_be64(f, STATTR_FLAG_DONE);
    }
    qemu_put_be64(f, STATTR_FLAG_EOS);

    r = qemu_file_get_error(f);
    if (r < 0) {
        return r;
    }

    return ret;
}

static int cmma_save_iterate(QEMUFile *f, void *opaque)
{
    return cmma_save(f, opaque, 0);
}

static int cmma_save_complete(QEMUFile *f, void *opaque)
{
    return cmma_save(f, opaque, 1);
}

static void cmma_save_cleanup(void *opaque)
{
    S390StAttribState *sas = S390_STATTRIB(opaque);
    S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
    sac->set_migrationmode(sas, false, NULL);
}

static bool cmma_active(void *opaque)
{
    S390StAttribState *sas = S390_STATTRIB(opaque);
    S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
    return sac->get_active(sas);
}

/* QEMU object: */

static void qemu_s390_stattrib_instance_init(Object *obj)
{
}

static int qemu_s390_peek_stattr_stub(S390StAttribState *sa, uint64_t start_gfn,
                                     uint32_t count, uint8_t *values)
{
    return 0;
}
static void qemu_s390_synchronize_stub(S390StAttribState *sa)
{
}
static int qemu_s390_get_stattr_stub(S390StAttribState *sa, uint64_t *start_gfn,
                                     uint32_t count, uint8_t *values)
{
    return 0;
}
static long long qemu_s390_get_dirtycount_stub(S390StAttribState *sa)
{
    return 0;
}
static int qemu_s390_set_migrationmode_stub(S390StAttribState *sa, bool value,
                                            Error **errp)
{
    return 0;
}

static int qemu_s390_get_active(S390StAttribState *sa)
{
    return sa->migration_enabled;
}

static void qemu_s390_stattrib_class_init(ObjectClass *oc, void *data)
{
    S390StAttribClass *sa_cl = S390_STATTRIB_CLASS(oc);
    DeviceClass *dc = DEVICE_CLASS(oc);

    sa_cl->synchronize = qemu_s390_synchronize_stub;
    sa_cl->get_stattr = qemu_s390_get_stattr_stub;
    sa_cl->set_stattr = qemu_s390_peek_stattr_stub;
    sa_cl->peek_stattr = qemu_s390_peek_stattr_stub;
    sa_cl->set_migrationmode = qemu_s390_set_migrationmode_stub;
    sa_cl->get_dirtycount = qemu_s390_get_dirtycount_stub;
    sa_cl->get_active = qemu_s390_get_active;

    /* Reason: Can only be instantiated one time (internally) */
    dc->user_creatable = false;
}

static const TypeInfo qemu_s390_stattrib_info = {
    .name          = TYPE_QEMU_S390_STATTRIB,
    .parent        = TYPE_S390_STATTRIB,
    .instance_init = qemu_s390_stattrib_instance_init,
    .instance_size = sizeof(QEMUS390StAttribState),
    .class_init    = qemu_s390_stattrib_class_init,
    .class_size    = sizeof(S390StAttribClass),
};

/* Generic abstract object: */

static SaveVMHandlers savevm_s390_stattrib_handlers = {
    .save_setup = cmma_save_setup,
    .save_live_iterate = cmma_save_iterate,
    .save_live_complete_precopy = cmma_save_complete,
    .state_pending_exact = cmma_state_pending,
    .state_pending_estimate = cmma_state_pending,
    .save_cleanup = cmma_save_cleanup,
    .load_state = cmma_load,
    .is_active = cmma_active,
};

static void s390_stattrib_realize(DeviceState *dev, Error **errp)
{
    bool ambiguous = false;

    object_resolve_path_type("", TYPE_S390_STATTRIB, &ambiguous);
    if (ambiguous) {
        error_setg(errp, "storage_attributes device already exists");
        return;
    }

    register_savevm_live(TYPE_S390_STATTRIB, 0, 0,
                         &savevm_s390_stattrib_handlers, dev);
}

static Property s390_stattrib_props[] = {
    DEFINE_PROP_BOOL("migration-enabled", S390StAttribState, migration_enabled, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void s390_stattrib_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->hotpluggable = false;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    dc->realize = s390_stattrib_realize;
    device_class_set_props(dc, s390_stattrib_props);
}

static void s390_stattrib_instance_init(Object *obj)
{
    S390StAttribState *sas = S390_STATTRIB(obj);

    sas->migration_cur_gfn = 0;
}

static const TypeInfo s390_stattrib_info = {
    .name          = TYPE_S390_STATTRIB,
    .parent        = TYPE_DEVICE,
    .instance_init = s390_stattrib_instance_init,
    .instance_size = sizeof(S390StAttribState),
    .class_init    = s390_stattrib_class_init,
    .class_size    = sizeof(S390StAttribClass),
    .abstract      = true,
};

static void s390_stattrib_register_types(void)
{
    type_register_static(&s390_stattrib_info);
    type_register_static(&qemu_s390_stattrib_info);
}

type_init(s390_stattrib_register_types)
