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

sclp.c (14820B)


      1/*
      2 * SCLP Support
      3 *
      4 * Copyright IBM, Corp. 2012
      5 *
      6 * Authors:
      7 *  Christian Borntraeger <borntraeger@de.ibm.com>
      8 *  Heinz Graalfs <graalfs@linux.vnet.ibm.com>
      9 *
     10 * This work is licensed under the terms of the GNU GPL, version 2 or (at your
     11 * option) any later version.  See the COPYING file in the top-level directory.
     12 *
     13 */
     14
     15#include "qemu/osdep.h"
     16#include "qemu/units.h"
     17#include "qapi/error.h"
     18#include "hw/boards.h"
     19#include "hw/s390x/sclp.h"
     20#include "hw/s390x/event-facility.h"
     21#include "hw/s390x/s390-pci-bus.h"
     22#include "hw/s390x/ipl.h"
     23
     24static inline SCLPDevice *get_sclp_device(void)
     25{
     26    static SCLPDevice *sclp;
     27
     28    if (!sclp) {
     29        sclp = SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
     30    }
     31    return sclp;
     32}
     33
     34static inline bool sclp_command_code_valid(uint32_t code)
     35{
     36    switch (code & SCLP_CMD_CODE_MASK) {
     37    case SCLP_CMDW_READ_SCP_INFO:
     38    case SCLP_CMDW_READ_SCP_INFO_FORCED:
     39    case SCLP_CMDW_READ_CPU_INFO:
     40    case SCLP_CMDW_CONFIGURE_IOA:
     41    case SCLP_CMDW_DECONFIGURE_IOA:
     42    case SCLP_CMD_READ_EVENT_DATA:
     43    case SCLP_CMD_WRITE_EVENT_DATA:
     44    case SCLP_CMD_WRITE_EVENT_MASK:
     45        return true;
     46    }
     47    return false;
     48}
     49
     50static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t sccb_len,
     51                                 uint32_t code)
     52{
     53    uint64_t sccb_max_addr = sccb_addr + sccb_len - 1;
     54    uint64_t sccb_boundary = (sccb_addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
     55
     56    switch (code & SCLP_CMD_CODE_MASK) {
     57    case SCLP_CMDW_READ_SCP_INFO:
     58    case SCLP_CMDW_READ_SCP_INFO_FORCED:
     59    case SCLP_CMDW_READ_CPU_INFO:
     60        /*
     61         * An extended-length SCCB is only allowed for Read SCP/CPU Info and
     62         * is allowed to exceed the 4k boundary. The respective commands will
     63         * set the length field to the required length if an insufficient
     64         * SCCB length is provided.
     65         */
     66        if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
     67            return true;
     68        }
     69        /* fallthrough */
     70    default:
     71        if (sccb_max_addr < sccb_boundary) {
     72            return true;
     73        }
     74    }
     75
     76    return false;
     77}
     78
     79static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
     80{
     81    uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
     82    int i;
     83
     84    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CPU, features);
     85    for (i = 0, *count = 0; i < ms->possible_cpus->len; i++) {
     86        if (!ms->possible_cpus->cpus[i].cpu) {
     87            continue;
     88        }
     89        entry[*count].address = ms->possible_cpus->cpus[i].arch_id;
     90        entry[*count].type = 0;
     91        memcpy(entry[*count].features, features, sizeof(features));
     92        (*count)++;
     93    }
     94}
     95
     96#define SCCB_REQ_LEN(s, max_cpus) (sizeof(s) + max_cpus * sizeof(CPUEntry))
     97
     98static inline bool ext_len_sccb_supported(SCCBHeader header)
     99{
    100    return s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) &&
    101           header.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE;
    102}
    103
    104/* Provide information about the configuration, CPUs and storage */
    105static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
    106{
    107    ReadInfo *read_info = (ReadInfo *) sccb;
    108    MachineState *machine = MACHINE(qdev_get_machine());
    109    int cpu_count;
    110    int rnsize, rnmax;
    111    IplParameterBlock *ipib = s390_ipl_get_iplb();
    112    int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
    113    int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
    114                     offsetof(ReadInfo, entries) :
    115                     SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
    116    CPUEntry *entries_start = (void *)sccb + offset_cpu;
    117
    118    if (be16_to_cpu(sccb->h.length) < required_len) {
    119        if (ext_len_sccb_supported(sccb->h)) {
    120            sccb->h.length = cpu_to_be16(required_len);
    121        }
    122        sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
    123        return;
    124    }
    125
    126    /* CPU information */
    127    prepare_cpu_entries(machine, entries_start, &cpu_count);
    128    read_info->entries_cpu = cpu_to_be16(cpu_count);
    129    read_info->offset_cpu = cpu_to_be16(offset_cpu);
    130    read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
    131
    132    read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
    133
    134    /* Configuration Characteristic (Extension) */
    135    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
    136                         read_info->conf_char);
    137    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
    138                         read_info->conf_char_ext);
    139
    140    if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
    141        s390_get_feat_block(S390_FEAT_TYPE_SCLP_FAC134,
    142                            &read_info->fac134);
    143    }
    144
    145    read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO |
    146                                        SCLP_HAS_IOA_RECONFIG);
    147
    148    read_info->mha_pow = s390_get_mha_pow();
    149    read_info->hmfai = cpu_to_be32(s390_get_hmfai());
    150
    151    rnsize = 1 << (sclp->increment_size - 20);
    152    if (rnsize <= 128) {
    153        read_info->rnsize = rnsize;
    154    } else {
    155        read_info->rnsize = 0;
    156        read_info->rnsize2 = cpu_to_be32(rnsize);
    157    }
    158
    159    /* we don't support standby memory, maxram_size is never exposed */
    160    rnmax = machine->ram_size >> sclp->increment_size;
    161    if (rnmax < 0x10000) {
    162        read_info->rnmax = cpu_to_be16(rnmax);
    163    } else {
    164        read_info->rnmax = cpu_to_be16(0);
    165        read_info->rnmax2 = cpu_to_be64(rnmax);
    166    }
    167
    168    if (ipib && ipib->flags & DIAG308_FLAGS_LP_VALID) {
    169        memcpy(&read_info->loadparm, &ipib->loadparm,
    170               sizeof(read_info->loadparm));
    171    } else {
    172        s390_ipl_set_loadparm(read_info->loadparm);
    173    }
    174
    175    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
    176}
    177
    178/* Provide information about the CPU */
    179static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
    180{
    181    MachineState *machine = MACHINE(qdev_get_machine());
    182    ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
    183    int cpu_count;
    184    int required_len = SCCB_REQ_LEN(ReadCpuInfo, machine->possible_cpus->len);
    185
    186    if (be16_to_cpu(sccb->h.length) < required_len) {
    187        if (ext_len_sccb_supported(sccb->h)) {
    188            sccb->h.length = cpu_to_be16(required_len);
    189        }
    190        sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
    191        return;
    192    }
    193
    194    prepare_cpu_entries(machine, cpu_info->entries, &cpu_count);
    195    cpu_info->nr_configured = cpu_to_be16(cpu_count);
    196    cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
    197    cpu_info->nr_standby = cpu_to_be16(0);
    198
    199    /* The standby offset is 16-byte for each CPU */
    200    cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
    201        + cpu_info->nr_configured*sizeof(CPUEntry));
    202
    203
    204    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
    205}
    206
    207static void sclp_configure_io_adapter(SCLPDevice *sclp, SCCB *sccb,
    208                                      bool configure)
    209{
    210    int rc;
    211
    212    if (be16_to_cpu(sccb->h.length) < 16) {
    213        rc = SCLP_RC_INSUFFICIENT_SCCB_LENGTH;
    214        goto out_err;
    215    }
    216
    217    switch (((IoaCfgSccb *)sccb)->atype) {
    218    case SCLP_RECONFIG_PCI_ATYPE:
    219        if (s390_has_feat(S390_FEAT_ZPCI)) {
    220            if (configure) {
    221                s390_pci_sclp_configure(sccb);
    222            } else {
    223                s390_pci_sclp_deconfigure(sccb);
    224            }
    225            return;
    226        }
    227        /* fallthrough */
    228    default:
    229        rc = SCLP_RC_ADAPTER_TYPE_NOT_RECOGNIZED;
    230    }
    231
    232 out_err:
    233    sccb->h.response_code = cpu_to_be16(rc);
    234}
    235
    236static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, uint32_t code)
    237{
    238    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
    239    SCLPEventFacility *ef = sclp->event_facility;
    240    SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef);
    241
    242    switch (code & SCLP_CMD_CODE_MASK) {
    243    case SCLP_CMDW_READ_SCP_INFO:
    244    case SCLP_CMDW_READ_SCP_INFO_FORCED:
    245        sclp_c->read_SCP_info(sclp, sccb);
    246        break;
    247    case SCLP_CMDW_READ_CPU_INFO:
    248        sclp_c->read_cpu_info(sclp, sccb);
    249        break;
    250    case SCLP_CMDW_CONFIGURE_IOA:
    251        sclp_configure_io_adapter(sclp, sccb, true);
    252        break;
    253    case SCLP_CMDW_DECONFIGURE_IOA:
    254        sclp_configure_io_adapter(sclp, sccb, false);
    255        break;
    256    default:
    257        efc->command_handler(ef, sccb, code);
    258        break;
    259    }
    260}
    261
    262/*
    263 * We only need the address to have something valid for the
    264 * service_interrupt call.
    265 */
    266#define SCLP_PV_DUMMY_ADDR 0x4000
    267int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
    268                                uint32_t code)
    269{
    270    SCLPDevice *sclp = get_sclp_device();
    271    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
    272    SCCBHeader header;
    273    g_autofree SCCB *work_sccb = NULL;
    274
    275    s390_cpu_pv_mem_read(env_archcpu(env), 0, &header, sizeof(SCCBHeader));
    276
    277    work_sccb = g_malloc0(be16_to_cpu(header.length));
    278    s390_cpu_pv_mem_read(env_archcpu(env), 0, work_sccb,
    279                         be16_to_cpu(header.length));
    280
    281    if (!sclp_command_code_valid(code)) {
    282        work_sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
    283        goto out_write;
    284    }
    285
    286    sclp_c->execute(sclp, work_sccb, code);
    287out_write:
    288    s390_cpu_pv_mem_write(env_archcpu(env), 0, work_sccb,
    289                          be16_to_cpu(work_sccb->h.length));
    290    sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR);
    291    return 0;
    292}
    293
    294int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
    295{
    296    SCLPDevice *sclp = get_sclp_device();
    297    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
    298    SCCBHeader header;
    299    g_autofree SCCB *work_sccb = NULL;
    300
    301    /* first some basic checks on program checks */
    302    if (env->psw.mask & PSW_MASK_PSTATE) {
    303        return -PGM_PRIVILEGED;
    304    }
    305    if (cpu_physical_memory_is_io(sccb)) {
    306        return -PGM_ADDRESSING;
    307    }
    308    if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
    309        || (sccb & ~0x7ffffff8UL) != 0) {
    310        return -PGM_SPECIFICATION;
    311    }
    312
    313    /* the header contains the actual length of the sccb */
    314    cpu_physical_memory_read(sccb, &header, sizeof(SCCBHeader));
    315
    316    /* Valid sccb sizes */
    317    if (be16_to_cpu(header.length) < sizeof(SCCBHeader)) {
    318        return -PGM_SPECIFICATION;
    319    }
    320
    321    /*
    322     * we want to work on a private copy of the sccb, to prevent guests
    323     * from playing dirty tricks by modifying the memory content after
    324     * the host has checked the values
    325     */
    326    work_sccb = g_malloc0(be16_to_cpu(header.length));
    327    cpu_physical_memory_read(sccb, work_sccb, be16_to_cpu(header.length));
    328
    329    if (!sclp_command_code_valid(code)) {
    330        work_sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
    331        goto out_write;
    332    }
    333
    334    if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb->h.length), code)) {
    335        work_sccb->h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
    336        goto out_write;
    337    }
    338
    339    sclp_c->execute(sclp, work_sccb, code);
    340out_write:
    341    cpu_physical_memory_write(sccb, work_sccb,
    342                              be16_to_cpu(work_sccb->h.length));
    343
    344    sclp_c->service_interrupt(sclp, sccb);
    345
    346    return 0;
    347}
    348
    349static void service_interrupt(SCLPDevice *sclp, uint32_t sccb)
    350{
    351    SCLPEventFacility *ef = sclp->event_facility;
    352    SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef);
    353
    354    uint32_t param = sccb & ~3;
    355
    356    /* Indicate whether an event is still pending */
    357    param |= efc->event_pending(ef) ? 1 : 0;
    358
    359    if (!param) {
    360        /* No need to send an interrupt, there's nothing to be notified about */
    361        return;
    362    }
    363    s390_sclp_extint(param);
    364}
    365
    366void sclp_service_interrupt(uint32_t sccb)
    367{
    368    SCLPDevice *sclp = get_sclp_device();
    369    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
    370
    371    sclp_c->service_interrupt(sclp, sccb);
    372}
    373
    374/* qemu object creation and initialization functions */
    375
    376void s390_sclp_init(void)
    377{
    378    Object *new = object_new(TYPE_SCLP);
    379
    380    object_property_add_child(qdev_get_machine(), TYPE_SCLP, new);
    381    object_unref(new);
    382    qdev_realize(DEVICE(new), NULL, &error_fatal);
    383}
    384
    385static void sclp_realize(DeviceState *dev, Error **errp)
    386{
    387    MachineState *machine = MACHINE(qdev_get_machine());
    388    SCLPDevice *sclp = SCLP(dev);
    389    uint64_t hw_limit;
    390    int ret;
    391
    392    /*
    393     * qdev_device_add searches the sysbus for TYPE_SCLP_EVENTS_BUS. As long
    394     * as we can't find a fitting bus via the qom tree, we have to add the
    395     * event facility to the sysbus, so e.g. a sclp console can be created.
    396     */
    397    if (!sysbus_realize(SYS_BUS_DEVICE(sclp->event_facility), errp)) {
    398        return;
    399    }
    400
    401    ret = s390_set_memory_limit(machine->maxram_size, &hw_limit);
    402    if (ret == -E2BIG) {
    403        error_setg(errp, "host supports a maximum of %" PRIu64 " GB",
    404                   hw_limit / GiB);
    405    } else if (ret) {
    406        error_setg(errp, "setting the guest size failed");
    407    }
    408}
    409
    410static void sclp_memory_init(SCLPDevice *sclp)
    411{
    412    MachineState *machine = MACHINE(qdev_get_machine());
    413    MachineClass *machine_class = MACHINE_GET_CLASS(qdev_get_machine());
    414    ram_addr_t initial_mem = machine->ram_size;
    415    int increment_size = 20;
    416
    417    /* The storage increment size is a multiple of 1M and is a power of 2.
    418     * For some machine types, the number of storage increments must be
    419     * MAX_STORAGE_INCREMENTS or fewer.
    420     * The variable 'increment_size' is an exponent of 2 that can be
    421     * used to calculate the size (in bytes) of an increment. */
    422    while (machine_class->fixup_ram_size != NULL &&
    423           (initial_mem >> increment_size) > MAX_STORAGE_INCREMENTS) {
    424        increment_size++;
    425    }
    426    sclp->increment_size = increment_size;
    427}
    428
    429static void sclp_init(Object *obj)
    430{
    431    SCLPDevice *sclp = SCLP(obj);
    432    Object *new;
    433
    434    new = object_new(TYPE_SCLP_EVENT_FACILITY);
    435    object_property_add_child(obj, TYPE_SCLP_EVENT_FACILITY, new);
    436    object_unref(new);
    437    sclp->event_facility = EVENT_FACILITY(new);
    438
    439    sclp_memory_init(sclp);
    440}
    441
    442static void sclp_class_init(ObjectClass *oc, void *data)
    443{
    444    SCLPDeviceClass *sc = SCLP_CLASS(oc);
    445    DeviceClass *dc = DEVICE_CLASS(oc);
    446
    447    dc->desc = "SCLP (Service-Call Logical Processor)";
    448    dc->realize = sclp_realize;
    449    dc->hotpluggable = false;
    450    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    451    /*
    452     * Reason: Creates TYPE_SCLP_EVENT_FACILITY in sclp_init
    453     * which is a non-pluggable sysbus device
    454     */
    455    dc->user_creatable = false;
    456
    457    sc->read_SCP_info = read_SCP_info;
    458    sc->read_cpu_info = sclp_read_cpu_info;
    459    sc->execute = sclp_execute;
    460    sc->service_interrupt = service_interrupt;
    461}
    462
    463static TypeInfo sclp_info = {
    464    .name = TYPE_SCLP,
    465    .parent = TYPE_DEVICE,
    466    .instance_init = sclp_init,
    467    .instance_size = sizeof(SCLPDevice),
    468    .class_init = sclp_class_init,
    469    .class_size = sizeof(SCLPDeviceClass),
    470};
    471
    472static void register_types(void)
    473{
    474    type_register_static(&sclp_info);
    475}
    476type_init(register_types);