qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

sclp.c (14826B)


      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 
     24 static 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 
     34 static 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 
     50 static 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 
     79 static 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 
     98 static 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 */
    105 static 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 */
    179 static 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 
    207 static 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 
    236 static 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
    267 int 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);
    287 out_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 
    294 int 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);
    340 out_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 
    349 static 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 
    366 void 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 
    376 void 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 
    385 static 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 
    410 static 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 
    429 static 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 
    442 static 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 
    463 static const 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 
    472 static void register_types(void)
    473 {
    474     type_register_static(&sclp_info);
    475 }
    476 type_init(register_types);