cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

arch_dump.c (7741B)


      1/*
      2 * writing ELF notes for s390x arch
      3 *
      4 *
      5 * Copyright IBM Corp. 2012, 2013
      6 *
      7 *     Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
      8 *
      9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
     10 * See the COPYING file in the top-level directory.
     11 *
     12 */
     13
     14#include "qemu/osdep.h"
     15#include "cpu.h"
     16#include "s390x-internal.h"
     17#include "elf.h"
     18#include "sysemu/dump.h"
     19
     20
     21struct S390xUserRegsStruct {
     22    uint64_t psw[2];
     23    uint64_t gprs[16];
     24    uint32_t acrs[16];
     25} QEMU_PACKED;
     26
     27typedef struct S390xUserRegsStruct S390xUserRegs;
     28
     29struct S390xElfPrstatusStruct {
     30    uint8_t pad1[32];
     31    uint32_t pid;
     32    uint8_t pad2[76];
     33    S390xUserRegs regs;
     34    uint8_t pad3[16];
     35} QEMU_PACKED;
     36
     37typedef struct S390xElfPrstatusStruct S390xElfPrstatus;
     38
     39struct S390xElfFpregsetStruct {
     40    uint32_t fpc;
     41    uint32_t pad;
     42    uint64_t fprs[16];
     43} QEMU_PACKED;
     44
     45typedef struct S390xElfFpregsetStruct S390xElfFpregset;
     46
     47struct S390xElfVregsLoStruct {
     48    uint64_t vregs[16];
     49} QEMU_PACKED;
     50
     51typedef struct S390xElfVregsLoStruct S390xElfVregsLo;
     52
     53struct S390xElfVregsHiStruct {
     54    uint64_t vregs[16][2];
     55} QEMU_PACKED;
     56
     57typedef struct S390xElfVregsHiStruct S390xElfVregsHi;
     58
     59struct S390xElfGSCBStruct {
     60    uint64_t gsregs[4];
     61} QEMU_PACKED;
     62
     63typedef struct S390xElfGSCBStruct S390xElfGSCB;
     64
     65typedef struct noteStruct {
     66    Elf64_Nhdr hdr;
     67    char name[8];
     68    union {
     69        S390xElfPrstatus prstatus;
     70        S390xElfFpregset fpregset;
     71        S390xElfVregsLo vregslo;
     72        S390xElfVregsHi vregshi;
     73        S390xElfGSCB gscb;
     74        uint32_t prefix;
     75        uint64_t timer;
     76        uint64_t todcmp;
     77        uint32_t todpreg;
     78        uint64_t ctrs[16];
     79    } contents;
     80} QEMU_PACKED Note;
     81
     82static void s390x_write_elf64_prstatus(Note *note, S390CPU *cpu, int id)
     83{
     84    int i;
     85    S390xUserRegs *regs;
     86
     87    note->hdr.n_type = cpu_to_be32(NT_PRSTATUS);
     88
     89    regs = &(note->contents.prstatus.regs);
     90    regs->psw[0] = cpu_to_be64(cpu->env.psw.mask);
     91    regs->psw[1] = cpu_to_be64(cpu->env.psw.addr);
     92    for (i = 0; i <= 15; i++) {
     93        regs->acrs[i] = cpu_to_be32(cpu->env.aregs[i]);
     94        regs->gprs[i] = cpu_to_be64(cpu->env.regs[i]);
     95    }
     96    note->contents.prstatus.pid = id;
     97}
     98
     99static void s390x_write_elf64_fpregset(Note *note, S390CPU *cpu, int id)
    100{
    101    int i;
    102    CPUS390XState *cs = &cpu->env;
    103
    104    note->hdr.n_type = cpu_to_be32(NT_FPREGSET);
    105    note->contents.fpregset.fpc = cpu_to_be32(cpu->env.fpc);
    106    for (i = 0; i <= 15; i++) {
    107        note->contents.fpregset.fprs[i] = cpu_to_be64(*get_freg(cs, i));
    108    }
    109}
    110
    111static void s390x_write_elf64_vregslo(Note *note, S390CPU *cpu,  int id)
    112{
    113    int i;
    114
    115    note->hdr.n_type = cpu_to_be32(NT_S390_VXRS_LOW);
    116    for (i = 0; i <= 15; i++) {
    117        note->contents.vregslo.vregs[i] = cpu_to_be64(cpu->env.vregs[i][1]);
    118    }
    119}
    120
    121static void s390x_write_elf64_vregshi(Note *note, S390CPU *cpu, int id)
    122{
    123    int i;
    124    S390xElfVregsHi *temp_vregshi;
    125
    126    temp_vregshi = &note->contents.vregshi;
    127
    128    note->hdr.n_type = cpu_to_be32(NT_S390_VXRS_HIGH);
    129    for (i = 0; i <= 15; i++) {
    130        temp_vregshi->vregs[i][0] = cpu_to_be64(cpu->env.vregs[i + 16][0]);
    131        temp_vregshi->vregs[i][1] = cpu_to_be64(cpu->env.vregs[i + 16][1]);
    132    }
    133}
    134
    135static void s390x_write_elf64_gscb(Note *note, S390CPU *cpu, int id)
    136{
    137    int i;
    138
    139    note->hdr.n_type = cpu_to_be32(NT_S390_GS_CB);
    140    for (i = 0; i < 4; i++) {
    141        note->contents.gscb.gsregs[i] = cpu_to_be64(cpu->env.gscb[i]);
    142    }
    143}
    144
    145static void s390x_write_elf64_timer(Note *note, S390CPU *cpu, int id)
    146{
    147    note->hdr.n_type = cpu_to_be32(NT_S390_TIMER);
    148    note->contents.timer = cpu_to_be64((uint64_t)(cpu->env.cputm));
    149}
    150
    151static void s390x_write_elf64_todcmp(Note *note, S390CPU *cpu, int id)
    152{
    153    note->hdr.n_type = cpu_to_be32(NT_S390_TODCMP);
    154    note->contents.todcmp = cpu_to_be64((uint64_t)(cpu->env.ckc));
    155}
    156
    157static void s390x_write_elf64_todpreg(Note *note, S390CPU *cpu, int id)
    158{
    159    note->hdr.n_type = cpu_to_be32(NT_S390_TODPREG);
    160    note->contents.todpreg = cpu_to_be32((uint32_t)(cpu->env.todpr));
    161}
    162
    163static void s390x_write_elf64_ctrs(Note *note, S390CPU *cpu, int id)
    164{
    165    int i;
    166
    167    note->hdr.n_type = cpu_to_be32(NT_S390_CTRS);
    168
    169    for (i = 0; i <= 15; i++) {
    170        note->contents.ctrs[i] = cpu_to_be64(cpu->env.cregs[i]);
    171    }
    172}
    173
    174static void s390x_write_elf64_prefix(Note *note, S390CPU *cpu, int id)
    175{
    176    note->hdr.n_type = cpu_to_be32(NT_S390_PREFIX);
    177    note->contents.prefix = cpu_to_be32((uint32_t)(cpu->env.psa));
    178}
    179
    180
    181typedef struct NoteFuncDescStruct {
    182    int contents_size;
    183    void (*note_contents_func)(Note *note, S390CPU *cpu, int id);
    184} NoteFuncDesc;
    185
    186static const NoteFuncDesc note_core[] = {
    187    {sizeof_field(Note, contents.prstatus), s390x_write_elf64_prstatus},
    188    {sizeof_field(Note, contents.fpregset), s390x_write_elf64_fpregset},
    189    { 0, NULL}
    190};
    191
    192static const NoteFuncDesc note_linux[] = {
    193    {sizeof_field(Note, contents.prefix),   s390x_write_elf64_prefix},
    194    {sizeof_field(Note, contents.ctrs),     s390x_write_elf64_ctrs},
    195    {sizeof_field(Note, contents.timer),    s390x_write_elf64_timer},
    196    {sizeof_field(Note, contents.todcmp),   s390x_write_elf64_todcmp},
    197    {sizeof_field(Note, contents.todpreg),  s390x_write_elf64_todpreg},
    198    {sizeof_field(Note, contents.vregslo),  s390x_write_elf64_vregslo},
    199    {sizeof_field(Note, contents.vregshi),  s390x_write_elf64_vregshi},
    200    {sizeof_field(Note, contents.gscb),     s390x_write_elf64_gscb},
    201    { 0, NULL}
    202};
    203
    204static int s390x_write_elf64_notes(const char *note_name,
    205                                       WriteCoreDumpFunction f,
    206                                       S390CPU *cpu, int id,
    207                                       void *opaque,
    208                                       const NoteFuncDesc *funcs)
    209{
    210    Note note;
    211    const NoteFuncDesc *nf;
    212    int note_size;
    213    int ret = -1;
    214
    215    assert(strlen(note_name) < sizeof(note.name));
    216
    217    for (nf = funcs; nf->note_contents_func; nf++) {
    218        memset(&note, 0, sizeof(note));
    219        note.hdr.n_namesz = cpu_to_be32(strlen(note_name) + 1);
    220        note.hdr.n_descsz = cpu_to_be32(nf->contents_size);
    221        g_strlcpy(note.name, note_name, sizeof(note.name));
    222        (*nf->note_contents_func)(&note, cpu, id);
    223
    224        note_size = sizeof(note) - sizeof(note.contents) + nf->contents_size;
    225        ret = f(&note, note_size, opaque);
    226
    227        if (ret < 0) {
    228            return -1;
    229        }
    230
    231    }
    232
    233    return 0;
    234}
    235
    236
    237int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
    238                              int cpuid, void *opaque)
    239{
    240    S390CPU *cpu = S390_CPU(cs);
    241    int r;
    242
    243    r = s390x_write_elf64_notes("CORE", f, cpu, cpuid, opaque, note_core);
    244    if (r) {
    245        return r;
    246    }
    247    return s390x_write_elf64_notes("LINUX", f, cpu, cpuid, opaque, note_linux);
    248}
    249
    250int cpu_get_dump_info(ArchDumpInfo *info,
    251                      const struct GuestPhysBlockList *guest_phys_blocks)
    252{
    253    info->d_machine = EM_S390;
    254    info->d_endian = ELFDATA2MSB;
    255    info->d_class = ELFCLASS64;
    256
    257    return 0;
    258}
    259
    260ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
    261{
    262    int name_size = 8; /* "LINUX" or "CORE" + pad */
    263    size_t elf_note_size = 0;
    264    int note_head_size;
    265    const NoteFuncDesc *nf;
    266
    267    assert(class == ELFCLASS64);
    268    assert(machine == EM_S390);
    269
    270    note_head_size = sizeof(Elf64_Nhdr);
    271
    272    for (nf = note_core; nf->note_contents_func; nf++) {
    273        elf_note_size = elf_note_size + note_head_size + name_size +
    274                        nf->contents_size;
    275    }
    276    for (nf = note_linux; nf->note_contents_func; nf++) {
    277        elf_note_size = elf_note_size + note_head_size + name_size +
    278                        nf->contents_size;
    279    }
    280
    281    return (elf_note_size) * nr_cpus;
    282}