/*
 * writing ELF notes for s390x arch
 *
 *
 * Copyright IBM Corp. 2012, 2013
 *
 *     Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
 *
 * 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/units.h"
#include "cpu.h"
#include "s390x-internal.h"
#include "elf.h"
#include "sysemu/dump.h"
#include "kvm/kvm_s390x.h"
#include "target/s390x/kvm/pv.h"

struct S390xUserRegsStruct {
    uint64_t psw[2];
    uint64_t gprs[16];
    uint32_t acrs[16];
} QEMU_PACKED;

typedef struct S390xUserRegsStruct S390xUserRegs;

struct S390xElfPrstatusStruct {
    uint8_t pad1[32];
    uint32_t pid;
    uint8_t pad2[76];
    S390xUserRegs regs;
    uint8_t pad3[16];
} QEMU_PACKED;

typedef struct S390xElfPrstatusStruct S390xElfPrstatus;

struct S390xElfFpregsetStruct {
    uint32_t fpc;
    uint32_t pad;
    uint64_t fprs[16];
} QEMU_PACKED;

typedef struct S390xElfFpregsetStruct S390xElfFpregset;

struct S390xElfVregsLoStruct {
    uint64_t vregs[16];
} QEMU_PACKED;

typedef struct S390xElfVregsLoStruct S390xElfVregsLo;

struct S390xElfVregsHiStruct {
    uint64_t vregs[16][2];
} QEMU_PACKED;

typedef struct S390xElfVregsHiStruct S390xElfVregsHi;

struct S390xElfGSCBStruct {
    uint64_t gsregs[4];
} QEMU_PACKED;

typedef struct S390xElfGSCBStruct S390xElfGSCB;

typedef struct noteStruct {
    Elf64_Nhdr hdr;
    char name[8];
    union {
        S390xElfPrstatus prstatus;
        S390xElfFpregset fpregset;
        S390xElfVregsLo vregslo;
        S390xElfVregsHi vregshi;
        S390xElfGSCB gscb;
        uint32_t prefix;
        uint64_t timer;
        uint64_t todcmp;
        uint32_t todpreg;
        uint64_t ctrs[16];
        uint8_t dynamic[1];  /*
                              * Would be a flexible array member, if
                              * that was legal inside a union. Real
                              * size comes from PV info interface.
                              */
    } contents;
} QEMU_PACKED Note;

static bool pv_dump_initialized;

static void s390x_write_elf64_prstatus(Note *note, S390CPU *cpu, int id)
{
    int i;
    S390xUserRegs *regs;

    note->hdr.n_type = cpu_to_be32(NT_PRSTATUS);

    regs = &(note->contents.prstatus.regs);
    regs->psw[0] = cpu_to_be64(cpu->env.psw.mask);
    regs->psw[1] = cpu_to_be64(cpu->env.psw.addr);
    for (i = 0; i <= 15; i++) {
        regs->acrs[i] = cpu_to_be32(cpu->env.aregs[i]);
        regs->gprs[i] = cpu_to_be64(cpu->env.regs[i]);
    }
    note->contents.prstatus.pid = cpu_to_be32(id);
}

static void s390x_write_elf64_fpregset(Note *note, S390CPU *cpu, int id)
{
    int i;
    CPUS390XState *cs = &cpu->env;

    note->hdr.n_type = cpu_to_be32(NT_FPREGSET);
    note->contents.fpregset.fpc = cpu_to_be32(cpu->env.fpc);
    for (i = 0; i <= 15; i++) {
        note->contents.fpregset.fprs[i] = cpu_to_be64(*get_freg(cs, i));
    }
}

static void s390x_write_elf64_vregslo(Note *note, S390CPU *cpu,  int id)
{
    int i;

    note->hdr.n_type = cpu_to_be32(NT_S390_VXRS_LOW);
    for (i = 0; i <= 15; i++) {
        note->contents.vregslo.vregs[i] = cpu_to_be64(cpu->env.vregs[i][1]);
    }
}

static void s390x_write_elf64_vregshi(Note *note, S390CPU *cpu, int id)
{
    int i;
    S390xElfVregsHi *temp_vregshi;

    temp_vregshi = &note->contents.vregshi;

    note->hdr.n_type = cpu_to_be32(NT_S390_VXRS_HIGH);
    for (i = 0; i <= 15; i++) {
        temp_vregshi->vregs[i][0] = cpu_to_be64(cpu->env.vregs[i + 16][0]);
        temp_vregshi->vregs[i][1] = cpu_to_be64(cpu->env.vregs[i + 16][1]);
    }
}

static void s390x_write_elf64_gscb(Note *note, S390CPU *cpu, int id)
{
    int i;

    note->hdr.n_type = cpu_to_be32(NT_S390_GS_CB);
    for (i = 0; i < 4; i++) {
        note->contents.gscb.gsregs[i] = cpu_to_be64(cpu->env.gscb[i]);
    }
}

static void s390x_write_elf64_timer(Note *note, S390CPU *cpu, int id)
{
    note->hdr.n_type = cpu_to_be32(NT_S390_TIMER);
    note->contents.timer = cpu_to_be64((uint64_t)(cpu->env.cputm));
}

static void s390x_write_elf64_todcmp(Note *note, S390CPU *cpu, int id)
{
    note->hdr.n_type = cpu_to_be32(NT_S390_TODCMP);
    note->contents.todcmp = cpu_to_be64((uint64_t)(cpu->env.ckc));
}

static void s390x_write_elf64_todpreg(Note *note, S390CPU *cpu, int id)
{
    note->hdr.n_type = cpu_to_be32(NT_S390_TODPREG);
    note->contents.todpreg = cpu_to_be32((uint32_t)(cpu->env.todpr));
}

static void s390x_write_elf64_ctrs(Note *note, S390CPU *cpu, int id)
{
    int i;

    note->hdr.n_type = cpu_to_be32(NT_S390_CTRS);

    for (i = 0; i <= 15; i++) {
        note->contents.ctrs[i] = cpu_to_be64(cpu->env.cregs[i]);
    }
}

static void s390x_write_elf64_prefix(Note *note, S390CPU *cpu, int id)
{
    note->hdr.n_type = cpu_to_be32(NT_S390_PREFIX);
    note->contents.prefix = cpu_to_be32((uint32_t)(cpu->env.psa));
}

static void s390x_write_elf64_pv(Note *note, S390CPU *cpu, int id)
{
    note->hdr.n_type = cpu_to_be32(NT_S390_PV_CPU_DATA);
    if (!pv_dump_initialized) {
        return;
    }
    kvm_s390_dump_cpu(cpu, &note->contents.dynamic);
}

typedef struct NoteFuncDescStruct {
    int contents_size;
    uint64_t (*note_size_func)(void); /* NULL for non-dynamic sized contents */
    void (*note_contents_func)(Note *note, S390CPU *cpu, int id);
    bool pvonly;
} NoteFuncDesc;

static const NoteFuncDesc note_core[] = {
    {sizeof_field(Note, contents.prstatus), NULL, s390x_write_elf64_prstatus, false},
    {sizeof_field(Note, contents.fpregset), NULL, s390x_write_elf64_fpregset, false},
    { 0, NULL, NULL, false}
};

static const NoteFuncDesc note_linux[] = {
    {sizeof_field(Note, contents.prefix),   NULL, s390x_write_elf64_prefix,  false},
    {sizeof_field(Note, contents.ctrs),     NULL, s390x_write_elf64_ctrs,    false},
    {sizeof_field(Note, contents.timer),    NULL, s390x_write_elf64_timer,   false},
    {sizeof_field(Note, contents.todcmp),   NULL, s390x_write_elf64_todcmp,  false},
    {sizeof_field(Note, contents.todpreg),  NULL, s390x_write_elf64_todpreg, false},
    {sizeof_field(Note, contents.vregslo),  NULL, s390x_write_elf64_vregslo, false},
    {sizeof_field(Note, contents.vregshi),  NULL, s390x_write_elf64_vregshi, false},
    {sizeof_field(Note, contents.gscb),     NULL, s390x_write_elf64_gscb,    false},
    {0, kvm_s390_pv_dmp_get_size_cpu,       s390x_write_elf64_pv, true},
    { 0, NULL, NULL, false}
};

static int s390x_write_elf64_notes(const char *note_name,
                                       WriteCoreDumpFunction f,
                                       S390CPU *cpu, int id,
                                       DumpState *s,
                                       const NoteFuncDesc *funcs)
{
    g_autofree Note *notep = NULL;
    const NoteFuncDesc *nf;
    int note_size, prev_size = 0, content_size;
    int ret = -1;

    assert(strlen(note_name) < sizeof(notep->name));

    for (nf = funcs; nf->note_contents_func; nf++) {
        if (nf->pvonly && !s390_is_pv()) {
            continue;
        }

        content_size = nf->note_size_func ? nf->note_size_func() : nf->contents_size;
        note_size = sizeof(Note) - sizeof(notep->contents) + content_size;

        if (prev_size < note_size) {
            g_free(notep);
            notep = g_malloc(note_size);
            prev_size = note_size;
        }

        memset(notep, 0, note_size);

        /* Setup note header data */
        notep->hdr.n_descsz = cpu_to_be32(content_size);
        notep->hdr.n_namesz = cpu_to_be32(strlen(note_name) + 1);
        g_strlcpy(notep->name, note_name, sizeof(notep->name));

        /* Get contents and write them out */
        (*nf->note_contents_func)(notep, cpu, id);
        ret = f(notep, note_size, s);
        if (ret < 0) {
            return -1;
        }
    }

    return 0;
}


int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
                              int cpuid, DumpState *s)
{
    S390CPU *cpu = S390_CPU(cs);
    int r;

    r = s390x_write_elf64_notes("CORE", f, cpu, cpuid, s, note_core);
    if (r) {
        return r;
    }
    return s390x_write_elf64_notes("LINUX", f, cpu, cpuid, s, note_linux);
}

/* PV dump section size functions */
static uint64_t get_mem_state_size_from_len(uint64_t len)
{
    return (len / (MiB)) * kvm_s390_pv_dmp_get_size_mem_state();
}

static uint64_t get_size_mem_state(DumpState *s)
{
    return get_mem_state_size_from_len(s->total_size);
}

static uint64_t get_size_completion_data(DumpState *s)
{
    return kvm_s390_pv_dmp_get_size_completion_data();
}

/* PV dump section data functions*/
static int get_data_completion(DumpState *s, uint8_t *buff)
{
    int rc;

    if (!pv_dump_initialized) {
        return 0;
    }
    rc = kvm_s390_dump_completion_data(buff);
    if (!rc) {
            pv_dump_initialized = false;
    }
    return rc;
}

static int get_mem_state(DumpState *s, uint8_t *buff)
{
    int64_t memblock_size, memblock_start;
    GuestPhysBlock *block;
    uint64_t off;
    int rc;

    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
        memblock_start = dump_filtered_memblock_start(block, s->filter_area_begin,
                                                      s->filter_area_length);
        if (memblock_start == -1) {
            continue;
        }

        memblock_size = dump_filtered_memblock_size(block, s->filter_area_begin,
                                                    s->filter_area_length);

        off = get_mem_state_size_from_len(block->target_start);

        rc = kvm_s390_dump_mem_state(block->target_start,
                                     get_mem_state_size_from_len(memblock_size),
                                     buff + off);
        if (rc) {
            return rc;
        }
    }

    return 0;
}

static struct sections {
    uint64_t (*sections_size_func)(DumpState *s);
    int (*sections_contents_func)(DumpState *s, uint8_t *buff);
    char sctn_str[12];
} sections[] = {
    { get_size_mem_state, get_mem_state, "pv_mem_meta"},
    { get_size_completion_data, get_data_completion, "pv_compl"},
    {NULL , NULL, ""}
};

static uint64_t arch_sections_write_hdr(DumpState *s, uint8_t *buff)
{
    Elf64_Shdr *shdr = (void *)buff;
    struct sections *sctn = sections;
    uint64_t off = s->section_offset;

    if (!pv_dump_initialized) {
        return 0;
    }

    for (; sctn->sections_size_func; off += shdr->sh_size, sctn++, shdr++) {
        memset(shdr, 0, sizeof(*shdr));
        shdr->sh_type = SHT_PROGBITS;
        shdr->sh_offset = off;
        shdr->sh_size = sctn->sections_size_func(s);
        shdr->sh_name = s->string_table_buf->len;
        g_array_append_vals(s->string_table_buf, sctn->sctn_str, sizeof(sctn->sctn_str));
    }

    return (uintptr_t)shdr - (uintptr_t)buff;
}


/* Add arch specific number of sections and their respective sizes */
static void arch_sections_add(DumpState *s)
{
    struct sections *sctn = sections;

    /*
     * We only do a PV dump if we are running a PV guest, KVM supports
     * the dump API and we got valid dump length information.
     */
    if (!s390_is_pv() || !kvm_s390_get_protected_dump() ||
        !kvm_s390_pv_info_basic_valid()) {
        return;
    }

    /*
     * Start the UV dump process by doing the initialize dump call via
     * KVM as the proxy.
     */
    if (!kvm_s390_dump_init()) {
        pv_dump_initialized = true;
    } else {
        /*
         * Dump init failed, maybe the guest owner disabled dumping.
         * We'll continue the non-PV dump process since this is no
         * reason to crash qemu.
         */
        return;
    }

    for (; sctn->sections_size_func; sctn++) {
        s->shdr_num += 1;
        s->elf_section_data_size += sctn->sections_size_func(s);
    }
}

/*
 * After the PV dump has been initialized, the CPU data has been
 * fetched and memory has been dumped, we need to grab the tweak data
 * and the completion data.
 */
static int arch_sections_write(DumpState *s, uint8_t *buff)
{
    struct sections *sctn = sections;
    int rc;

    if (!pv_dump_initialized) {
        return -EINVAL;
    }

    for (; sctn->sections_size_func; sctn++) {
        rc = sctn->sections_contents_func(s, buff);
        buff += sctn->sections_size_func(s);
        if (rc) {
            return rc;
        }
    }
    return 0;
}

static void arch_cleanup(DumpState *s)
{
    g_autofree uint8_t *buff = NULL;
    int rc;

    if (!pv_dump_initialized) {
        return;
    }

    buff = g_malloc(kvm_s390_pv_dmp_get_size_completion_data());
    rc = kvm_s390_dump_completion_data(buff);
    if (!rc) {
            pv_dump_initialized = false;
    }
}

int cpu_get_dump_info(ArchDumpInfo *info,
                      const struct GuestPhysBlockList *guest_phys_blocks)
{
    info->d_machine = EM_S390;
    info->d_endian = ELFDATA2MSB;
    info->d_class = ELFCLASS64;
    /*
     * This is evaluated for each dump so we can freely switch
     * between PV and non-PV.
     */
    if (s390_is_pv() && kvm_s390_get_protected_dump() &&
        kvm_s390_pv_info_basic_valid()) {
        info->arch_sections_add_fn = *arch_sections_add;
        info->arch_sections_write_hdr_fn = *arch_sections_write_hdr;
        info->arch_sections_write_fn = *arch_sections_write;
        info->arch_cleanup_fn = *arch_cleanup;
    }
    return 0;
}

ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
{
    int name_size = 8; /* "LINUX" or "CORE" + pad */
    size_t elf_note_size = 0;
    int note_head_size, content_size;
    const NoteFuncDesc *nf;

    assert(class == ELFCLASS64);
    assert(machine == EM_S390);

    note_head_size = sizeof(Elf64_Nhdr);

    for (nf = note_core; nf->note_contents_func; nf++) {
        elf_note_size = elf_note_size + note_head_size + name_size + nf->contents_size;
    }
    for (nf = note_linux; nf->note_contents_func; nf++) {
        if (nf->pvonly && !s390_is_pv()) {
            continue;
        }
        content_size = nf->contents_size ? nf->contents_size : nf->note_size_func();
        elf_note_size = elf_note_size + note_head_size + name_size +
                        content_size;
    }

    return (elf_note_size) * nr_cpus;
}
