qemu

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

ioinst.c (22668B)


      1 /*
      2  * I/O instructions for S/390
      3  *
      4  * Copyright 2012, 2015 IBM Corp.
      5  * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
      6  *
      7  * This work is licensed under the terms of the GNU GPL, version 2 or (at
      8  * your option) any later version. See the COPYING file in the top-level
      9  * directory.
     10  */
     11 
     12 #include "qemu/osdep.h"
     13 
     14 #include "cpu.h"
     15 #include "s390x-internal.h"
     16 #include "hw/s390x/ioinst.h"
     17 #include "trace.h"
     18 #include "hw/s390x/s390-pci-bus.h"
     19 #include "hw/s390x/pv.h"
     20 
     21 /* All I/O instructions but chsc use the s format */
     22 static uint64_t get_address_from_regs(CPUS390XState *env, uint32_t ipb,
     23                                       uint8_t *ar)
     24 {
     25     /*
     26      * Addresses for protected guests are all offsets into the
     27      * satellite block which holds the IO control structures. Those
     28      * control structures are always starting at offset 0 and are
     29      * always aligned and accessible. So we can return 0 here which
     30      * will pass the following address checks.
     31      */
     32     if (s390_is_pv()) {
     33         *ar = 0;
     34         return 0;
     35     }
     36     return decode_basedisp_s(env, ipb, ar);
     37 }
     38 
     39 int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
     40                                  int *schid)
     41 {
     42     if (!IOINST_SCHID_ONE(value)) {
     43         return -EINVAL;
     44     }
     45     if (!IOINST_SCHID_M(value)) {
     46         if (IOINST_SCHID_CSSID(value)) {
     47             return -EINVAL;
     48         }
     49         *cssid = 0;
     50         *m = 0;
     51     } else {
     52         *cssid = IOINST_SCHID_CSSID(value);
     53         *m = 1;
     54     }
     55     *ssid = IOINST_SCHID_SSID(value);
     56     *schid = IOINST_SCHID_NR(value);
     57     return 0;
     58 }
     59 
     60 void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
     61 {
     62     int cssid, ssid, schid, m;
     63     SubchDev *sch;
     64 
     65     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
     66         s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
     67         return;
     68     }
     69     trace_ioinst_sch_id("xsch", cssid, ssid, schid);
     70     sch = css_find_subch(m, cssid, ssid, schid);
     71     if (!sch || !css_subch_visible(sch)) {
     72         setcc(cpu, 3);
     73         return;
     74     }
     75     setcc(cpu, css_do_xsch(sch));
     76 }
     77 
     78 void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
     79 {
     80     int cssid, ssid, schid, m;
     81     SubchDev *sch;
     82 
     83     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
     84         s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
     85         return;
     86     }
     87     trace_ioinst_sch_id("csch", cssid, ssid, schid);
     88     sch = css_find_subch(m, cssid, ssid, schid);
     89     if (!sch || !css_subch_visible(sch)) {
     90         setcc(cpu, 3);
     91         return;
     92     }
     93     setcc(cpu, css_do_csch(sch));
     94 }
     95 
     96 void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
     97 {
     98     int cssid, ssid, schid, m;
     99     SubchDev *sch;
    100 
    101     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
    102         s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
    103         return;
    104     }
    105     trace_ioinst_sch_id("hsch", cssid, ssid, schid);
    106     sch = css_find_subch(m, cssid, ssid, schid);
    107     if (!sch || !css_subch_visible(sch)) {
    108         setcc(cpu, 3);
    109         return;
    110     }
    111     setcc(cpu, css_do_hsch(sch));
    112 }
    113 
    114 static int ioinst_schib_valid(SCHIB *schib)
    115 {
    116     if ((be16_to_cpu(schib->pmcw.flags) & PMCW_FLAGS_MASK_INVALID) ||
    117         (be32_to_cpu(schib->pmcw.chars) & PMCW_CHARS_MASK_INVALID)) {
    118         return 0;
    119     }
    120     /* Disallow extended measurements for now. */
    121     if (be32_to_cpu(schib->pmcw.chars) & PMCW_CHARS_MASK_XMWME) {
    122         return 0;
    123     }
    124     /* for MB format 1 bits 26-31 of word 11 must be 0 */
    125     /* MBA uses words 10 and 11, it means align on 2**6 */
    126     if ((be32_to_cpu(schib->pmcw.chars) & PMCW_CHARS_MASK_MBFC) &&
    127         (be64_to_cpu(schib->mba) & 0x03fUL)) {
    128         return 0;
    129     }
    130     return 1;
    131 }
    132 
    133 void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
    134 {
    135     int cssid, ssid, schid, m;
    136     SubchDev *sch;
    137     SCHIB schib;
    138     uint64_t addr;
    139     CPUS390XState *env = &cpu->env;
    140     uint8_t ar;
    141 
    142     addr = get_address_from_regs(env, ipb, &ar);
    143     if (addr & 3) {
    144         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
    145         return;
    146     }
    147     if (s390_is_pv()) {
    148         s390_cpu_pv_mem_read(cpu, addr, &schib, sizeof(schib));
    149     } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
    150         s390_cpu_virt_mem_handle_exc(cpu, ra);
    151         return;
    152     }
    153     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
    154         !ioinst_schib_valid(&schib)) {
    155         s390_program_interrupt(env, PGM_OPERAND, ra);
    156         return;
    157     }
    158     trace_ioinst_sch_id("msch", cssid, ssid, schid);
    159     sch = css_find_subch(m, cssid, ssid, schid);
    160     if (!sch || !css_subch_visible(sch)) {
    161         setcc(cpu, 3);
    162         return;
    163     }
    164     setcc(cpu, css_do_msch(sch, &schib));
    165 }
    166 
    167 static void copy_orb_from_guest(ORB *dest, const ORB *src)
    168 {
    169     dest->intparm = be32_to_cpu(src->intparm);
    170     dest->ctrl0 = be16_to_cpu(src->ctrl0);
    171     dest->lpm = src->lpm;
    172     dest->ctrl1 = src->ctrl1;
    173     dest->cpa = be32_to_cpu(src->cpa);
    174 }
    175 
    176 static int ioinst_orb_valid(ORB *orb)
    177 {
    178     if ((orb->ctrl0 & ORB_CTRL0_MASK_INVALID) ||
    179         (orb->ctrl1 & ORB_CTRL1_MASK_INVALID)) {
    180         return 0;
    181     }
    182     /* We don't support MIDA. */
    183     if (orb->ctrl1 & ORB_CTRL1_MASK_MIDAW) {
    184         return 0;
    185     }
    186     if ((orb->cpa & HIGH_ORDER_BIT) != 0) {
    187         return 0;
    188     }
    189     return 1;
    190 }
    191 
    192 void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
    193 {
    194     int cssid, ssid, schid, m;
    195     SubchDev *sch;
    196     ORB orig_orb, orb;
    197     uint64_t addr;
    198     CPUS390XState *env = &cpu->env;
    199     uint8_t ar;
    200 
    201     addr = get_address_from_regs(env, ipb, &ar);
    202     if (addr & 3) {
    203         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
    204         return;
    205     }
    206     if (s390_is_pv()) {
    207         s390_cpu_pv_mem_read(cpu, addr, &orig_orb, sizeof(orb));
    208     } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
    209         s390_cpu_virt_mem_handle_exc(cpu, ra);
    210         return;
    211     }
    212     copy_orb_from_guest(&orb, &orig_orb);
    213     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
    214         !ioinst_orb_valid(&orb)) {
    215         s390_program_interrupt(env, PGM_OPERAND, ra);
    216         return;
    217     }
    218     trace_ioinst_sch_id("ssch", cssid, ssid, schid);
    219     sch = css_find_subch(m, cssid, ssid, schid);
    220     if (!sch || !css_subch_visible(sch)) {
    221         setcc(cpu, 3);
    222         return;
    223     }
    224     setcc(cpu, css_do_ssch(sch, &orb));
    225 }
    226 
    227 void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
    228 {
    229     CRW crw;
    230     uint64_t addr;
    231     int cc;
    232     CPUS390XState *env = &cpu->env;
    233     uint8_t ar;
    234 
    235     addr = get_address_from_regs(env, ipb, &ar);
    236     if (addr & 3) {
    237         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
    238         return;
    239     }
    240 
    241     cc = css_do_stcrw(&crw);
    242     /* 0 - crw stored, 1 - zeroes stored */
    243 
    244     if (s390_is_pv()) {
    245         s390_cpu_pv_mem_write(cpu, addr, &crw, sizeof(crw));
    246         setcc(cpu, cc);
    247     } else {
    248         if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
    249             setcc(cpu, cc);
    250         } else {
    251             if (cc == 0) {
    252                 /* Write failed: requeue CRW since STCRW is suppressing */
    253                 css_undo_stcrw(&crw);
    254             }
    255             s390_cpu_virt_mem_handle_exc(cpu, ra);
    256         }
    257     }
    258 }
    259 
    260 void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
    261                          uintptr_t ra)
    262 {
    263     int cssid, ssid, schid, m;
    264     SubchDev *sch;
    265     uint64_t addr;
    266     int cc;
    267     SCHIB schib;
    268     CPUS390XState *env = &cpu->env;
    269     uint8_t ar;
    270 
    271     addr = get_address_from_regs(env, ipb, &ar);
    272     if (addr & 3) {
    273         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
    274         return;
    275     }
    276 
    277     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
    278         /*
    279          * The Ultravisor checks schid bit 16 to be one and bits 0-12
    280          * to be 0 and injects a operand exception itself.
    281          *
    282          * Hence we should never end up here.
    283          */
    284         g_assert(!s390_is_pv());
    285         /*
    286          * As operand exceptions have a lower priority than access exceptions,
    287          * we check whether the memory area is writable (injecting the
    288          * access exception if it is not) first.
    289          */
    290         if (!s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib))) {
    291             s390_program_interrupt(env, PGM_OPERAND, ra);
    292         } else {
    293             s390_cpu_virt_mem_handle_exc(cpu, ra);
    294         }
    295         return;
    296     }
    297     trace_ioinst_sch_id("stsch", cssid, ssid, schid);
    298     sch = css_find_subch(m, cssid, ssid, schid);
    299     if (sch) {
    300         if (css_subch_visible(sch)) {
    301             cc = css_do_stsch(sch, &schib);
    302         } else {
    303             /* Indicate no more subchannels in this css/ss */
    304             cc = 3;
    305         }
    306     } else {
    307         if (css_schid_final(m, cssid, ssid, schid)) {
    308             cc = 3; /* No more subchannels in this css/ss */
    309         } else {
    310             /* Store an empty schib. */
    311             memset(&schib, 0, sizeof(schib));
    312             cc = 0;
    313         }
    314     }
    315     if (cc != 3) {
    316         if (s390_is_pv()) {
    317             s390_cpu_pv_mem_write(cpu, addr, &schib, sizeof(schib));
    318         } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
    319                                            sizeof(schib)) != 0) {
    320             s390_cpu_virt_mem_handle_exc(cpu, ra);
    321             return;
    322         }
    323     } else {
    324         /* Access exceptions have a higher priority than cc3 */
    325         if (!s390_is_pv() &&
    326             s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
    327             s390_cpu_virt_mem_handle_exc(cpu, ra);
    328             return;
    329         }
    330     }
    331     setcc(cpu, cc);
    332 }
    333 
    334 int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
    335 {
    336     CPUS390XState *env = &cpu->env;
    337     int cssid, ssid, schid, m;
    338     SubchDev *sch;
    339     IRB irb;
    340     uint64_t addr;
    341     int cc, irb_len;
    342     uint8_t ar;
    343 
    344     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
    345         s390_program_interrupt(env, PGM_OPERAND, ra);
    346         return -EIO;
    347     }
    348     trace_ioinst_sch_id("tsch", cssid, ssid, schid);
    349     addr = get_address_from_regs(env, ipb, &ar);
    350     if (addr & 3) {
    351         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
    352         return -EIO;
    353     }
    354 
    355     sch = css_find_subch(m, cssid, ssid, schid);
    356     if (sch && css_subch_visible(sch)) {
    357         cc = css_do_tsch_get_irb(sch, &irb, &irb_len);
    358     } else {
    359         cc = 3;
    360     }
    361     /* 0 - status pending, 1 - not status pending, 3 - not operational */
    362     if (cc != 3) {
    363         if (s390_is_pv()) {
    364             s390_cpu_pv_mem_write(cpu, addr, &irb, irb_len);
    365         } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
    366             s390_cpu_virt_mem_handle_exc(cpu, ra);
    367             return -EFAULT;
    368         }
    369         css_do_tsch_update_subch(sch);
    370     } else {
    371         irb_len = sizeof(irb) - sizeof(irb.emw);
    372         /* Access exceptions have a higher priority than cc3 */
    373         if (!s390_is_pv() &&
    374             s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
    375             s390_cpu_virt_mem_handle_exc(cpu, ra);
    376             return -EFAULT;
    377         }
    378     }
    379 
    380     setcc(cpu, cc);
    381     return 0;
    382 }
    383 
    384 typedef struct ChscReq {
    385     uint16_t len;
    386     uint16_t command;
    387     uint32_t param0;
    388     uint32_t param1;
    389     uint32_t param2;
    390 } QEMU_PACKED ChscReq;
    391 
    392 typedef struct ChscResp {
    393     uint16_t len;
    394     uint16_t code;
    395     uint32_t param;
    396     char data[];
    397 } QEMU_PACKED ChscResp;
    398 
    399 #define CHSC_MIN_RESP_LEN 0x0008
    400 
    401 #define CHSC_SCPD 0x0002
    402 #define CHSC_SCSC 0x0010
    403 #define CHSC_SDA  0x0031
    404 #define CHSC_SEI  0x000e
    405 
    406 #define CHSC_SCPD_0_M 0x20000000
    407 #define CHSC_SCPD_0_C 0x10000000
    408 #define CHSC_SCPD_0_FMT 0x0f000000
    409 #define CHSC_SCPD_0_CSSID 0x00ff0000
    410 #define CHSC_SCPD_0_RFMT 0x00000f00
    411 #define CHSC_SCPD_0_RES 0xc000f000
    412 #define CHSC_SCPD_1_RES 0xffffff00
    413 #define CHSC_SCPD_01_CHPID 0x000000ff
    414 static void ioinst_handle_chsc_scpd(ChscReq *req, ChscResp *res)
    415 {
    416     uint16_t len = be16_to_cpu(req->len);
    417     uint32_t param0 = be32_to_cpu(req->param0);
    418     uint32_t param1 = be32_to_cpu(req->param1);
    419     uint16_t resp_code;
    420     int rfmt;
    421     uint16_t cssid;
    422     uint8_t f_chpid, l_chpid;
    423     int desc_size;
    424     int m;
    425 
    426     rfmt = (param0 & CHSC_SCPD_0_RFMT) >> 8;
    427     if ((rfmt == 0) ||  (rfmt == 1)) {
    428         rfmt = !!(param0 & CHSC_SCPD_0_C);
    429     }
    430     if ((len != 0x0010) || (param0 & CHSC_SCPD_0_RES) ||
    431         (param1 & CHSC_SCPD_1_RES) || req->param2) {
    432         resp_code = 0x0003;
    433         goto out_err;
    434     }
    435     if (param0 & CHSC_SCPD_0_FMT) {
    436         resp_code = 0x0007;
    437         goto out_err;
    438     }
    439     cssid = (param0 & CHSC_SCPD_0_CSSID) >> 16;
    440     m = param0 & CHSC_SCPD_0_M;
    441     if (cssid != 0) {
    442         if (!m || !css_present(cssid)) {
    443             resp_code = 0x0008;
    444             goto out_err;
    445         }
    446     }
    447     f_chpid = param0 & CHSC_SCPD_01_CHPID;
    448     l_chpid = param1 & CHSC_SCPD_01_CHPID;
    449     if (l_chpid < f_chpid) {
    450         resp_code = 0x0003;
    451         goto out_err;
    452     }
    453     /* css_collect_chp_desc() is endian-aware */
    454     desc_size = css_collect_chp_desc(m, cssid, f_chpid, l_chpid, rfmt,
    455                                      &res->data);
    456     res->code = cpu_to_be16(0x0001);
    457     res->len = cpu_to_be16(8 + desc_size);
    458     res->param = cpu_to_be32(rfmt);
    459     return;
    460 
    461   out_err:
    462     res->code = cpu_to_be16(resp_code);
    463     res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
    464     res->param = cpu_to_be32(rfmt);
    465 }
    466 
    467 #define CHSC_SCSC_0_M 0x20000000
    468 #define CHSC_SCSC_0_FMT 0x000f0000
    469 #define CHSC_SCSC_0_CSSID 0x0000ff00
    470 #define CHSC_SCSC_0_RES 0xdff000ff
    471 static void ioinst_handle_chsc_scsc(ChscReq *req, ChscResp *res)
    472 {
    473     uint16_t len = be16_to_cpu(req->len);
    474     uint32_t param0 = be32_to_cpu(req->param0);
    475     uint8_t cssid;
    476     uint16_t resp_code;
    477     uint32_t general_chars[510];
    478     uint32_t chsc_chars[508];
    479 
    480     if (len != 0x0010) {
    481         resp_code = 0x0003;
    482         goto out_err;
    483     }
    484 
    485     if (param0 & CHSC_SCSC_0_FMT) {
    486         resp_code = 0x0007;
    487         goto out_err;
    488     }
    489     cssid = (param0 & CHSC_SCSC_0_CSSID) >> 8;
    490     if (cssid != 0) {
    491         if (!(param0 & CHSC_SCSC_0_M) || !css_present(cssid)) {
    492             resp_code = 0x0008;
    493             goto out_err;
    494         }
    495     }
    496     if ((param0 & CHSC_SCSC_0_RES) || req->param1 || req->param2) {
    497         resp_code = 0x0003;
    498         goto out_err;
    499     }
    500     res->code = cpu_to_be16(0x0001);
    501     res->len = cpu_to_be16(4080);
    502     res->param = 0;
    503 
    504     memset(general_chars, 0, sizeof(general_chars));
    505     memset(chsc_chars, 0, sizeof(chsc_chars));
    506 
    507     general_chars[0] = cpu_to_be32(0x03000000);
    508     general_chars[1] = cpu_to_be32(0x00079000);
    509     general_chars[3] = cpu_to_be32(0x00080000);
    510 
    511     chsc_chars[0] = cpu_to_be32(0x40000000);
    512     chsc_chars[3] = cpu_to_be32(0x00040000);
    513 
    514     memcpy(res->data, general_chars, sizeof(general_chars));
    515     memcpy(res->data + sizeof(general_chars), chsc_chars, sizeof(chsc_chars));
    516     return;
    517 
    518   out_err:
    519     res->code = cpu_to_be16(resp_code);
    520     res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
    521     res->param = 0;
    522 }
    523 
    524 #define CHSC_SDA_0_FMT 0x0f000000
    525 #define CHSC_SDA_0_OC 0x0000ffff
    526 #define CHSC_SDA_0_RES 0xf0ff0000
    527 #define CHSC_SDA_OC_MCSSE 0x0
    528 #define CHSC_SDA_OC_MSS 0x2
    529 static void ioinst_handle_chsc_sda(ChscReq *req, ChscResp *res)
    530 {
    531     uint16_t resp_code = 0x0001;
    532     uint16_t len = be16_to_cpu(req->len);
    533     uint32_t param0 = be32_to_cpu(req->param0);
    534     uint16_t oc;
    535     int ret;
    536 
    537     if ((len != 0x0400) || (param0 & CHSC_SDA_0_RES)) {
    538         resp_code = 0x0003;
    539         goto out;
    540     }
    541 
    542     if (param0 & CHSC_SDA_0_FMT) {
    543         resp_code = 0x0007;
    544         goto out;
    545     }
    546 
    547     oc = param0 & CHSC_SDA_0_OC;
    548     switch (oc) {
    549     case CHSC_SDA_OC_MCSSE:
    550         ret = css_enable_mcsse();
    551         if (ret == -EINVAL) {
    552             resp_code = 0x0101;
    553             goto out;
    554         }
    555         break;
    556     case CHSC_SDA_OC_MSS:
    557         ret = css_enable_mss();
    558         if (ret == -EINVAL) {
    559             resp_code = 0x0101;
    560             goto out;
    561         }
    562         break;
    563     default:
    564         resp_code = 0x0003;
    565         goto out;
    566     }
    567 
    568 out:
    569     res->code = cpu_to_be16(resp_code);
    570     res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
    571     res->param = 0;
    572 }
    573 
    574 static int chsc_sei_nt0_get_event(void *res)
    575 {
    576     /* no events yet */
    577     return 1;
    578 }
    579 
    580 static int chsc_sei_nt0_have_event(void)
    581 {
    582     /* no events yet */
    583     return 0;
    584 }
    585 
    586 static int chsc_sei_nt2_get_event(void *res)
    587 {
    588     if (s390_has_feat(S390_FEAT_ZPCI)) {
    589         return pci_chsc_sei_nt2_get_event(res);
    590     }
    591     return 1;
    592 }
    593 
    594 static int chsc_sei_nt2_have_event(void)
    595 {
    596     if (s390_has_feat(S390_FEAT_ZPCI)) {
    597         return pci_chsc_sei_nt2_have_event();
    598     }
    599     return 0;
    600 }
    601 
    602 #define CHSC_SEI_NT0    (1ULL << 63)
    603 #define CHSC_SEI_NT2    (1ULL << 61)
    604 static void ioinst_handle_chsc_sei(ChscReq *req, ChscResp *res)
    605 {
    606     uint64_t selection_mask = ldq_p(&req->param1);
    607     uint8_t *res_flags = (uint8_t *)res->data;
    608     int have_event = 0;
    609     int have_more = 0;
    610 
    611     /* regarding architecture nt0 can not be masked */
    612     have_event = !chsc_sei_nt0_get_event(res);
    613     have_more = chsc_sei_nt0_have_event();
    614 
    615     if (selection_mask & CHSC_SEI_NT2) {
    616         if (!have_event) {
    617             have_event = !chsc_sei_nt2_get_event(res);
    618         }
    619 
    620         if (!have_more) {
    621             have_more = chsc_sei_nt2_have_event();
    622         }
    623     }
    624 
    625     if (have_event) {
    626         res->code = cpu_to_be16(0x0001);
    627         if (have_more) {
    628             (*res_flags) |= 0x80;
    629         } else {
    630             (*res_flags) &= ~0x80;
    631             css_clear_sei_pending();
    632         }
    633     } else {
    634         res->code = cpu_to_be16(0x0005);
    635         res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
    636     }
    637 }
    638 
    639 static void ioinst_handle_chsc_unimplemented(ChscResp *res)
    640 {
    641     res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
    642     res->code = cpu_to_be16(0x0004);
    643     res->param = 0;
    644 }
    645 
    646 void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
    647 {
    648     ChscReq *req;
    649     ChscResp *res;
    650     uint64_t addr = 0;
    651     int reg;
    652     uint16_t len;
    653     uint16_t command;
    654     CPUS390XState *env = &cpu->env;
    655     uint8_t buf[TARGET_PAGE_SIZE];
    656 
    657     trace_ioinst("chsc");
    658     reg = (ipb >> 20) & 0x00f;
    659     if (!s390_is_pv()) {
    660         addr = env->regs[reg];
    661     }
    662     /* Page boundary? */
    663     if (addr & 0xfff) {
    664         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
    665         return;
    666     }
    667     /*
    668      * Reading sizeof(ChscReq) bytes is currently enough for all of our
    669      * present CHSC sub-handlers ... if we ever need more, we should take
    670      * care of req->len here first.
    671      */
    672     if (s390_is_pv()) {
    673         s390_cpu_pv_mem_read(cpu, addr, buf, sizeof(ChscReq));
    674     } else if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
    675         s390_cpu_virt_mem_handle_exc(cpu, ra);
    676         return;
    677     }
    678     req = (ChscReq *)buf;
    679     len = be16_to_cpu(req->len);
    680     /* Length field valid? */
    681     if ((len < 16) || (len > 4088) || (len & 7)) {
    682         s390_program_interrupt(env, PGM_OPERAND, ra);
    683         return;
    684     }
    685     memset((char *)req + len, 0, TARGET_PAGE_SIZE - len);
    686     res = (void *)((char *)req + len);
    687     command = be16_to_cpu(req->command);
    688     trace_ioinst_chsc_cmd(command, len);
    689     switch (command) {
    690     case CHSC_SCSC:
    691         ioinst_handle_chsc_scsc(req, res);
    692         break;
    693     case CHSC_SCPD:
    694         ioinst_handle_chsc_scpd(req, res);
    695         break;
    696     case CHSC_SDA:
    697         ioinst_handle_chsc_sda(req, res);
    698         break;
    699     case CHSC_SEI:
    700         ioinst_handle_chsc_sei(req, res);
    701         break;
    702     default:
    703         ioinst_handle_chsc_unimplemented(res);
    704         break;
    705     }
    706 
    707     if (s390_is_pv()) {
    708         s390_cpu_pv_mem_write(cpu, addr + len, res, be16_to_cpu(res->len));
    709         setcc(cpu, 0);    /* Command execution complete */
    710     } else {
    711         if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
    712                                      be16_to_cpu(res->len))) {
    713             setcc(cpu, 0);    /* Command execution complete */
    714         } else {
    715             s390_cpu_virt_mem_handle_exc(cpu, ra);
    716         }
    717     }
    718 }
    719 
    720 #define SCHM_REG1_RES(_reg) (_reg & 0x000000000ffffffc)
    721 #define SCHM_REG1_MBK(_reg) ((_reg & 0x00000000f0000000) >> 28)
    722 #define SCHM_REG1_UPD(_reg) ((_reg & 0x0000000000000002) >> 1)
    723 #define SCHM_REG1_DCT(_reg) (_reg & 0x0000000000000001)
    724 
    725 void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
    726                         uint32_t ipb, uintptr_t ra)
    727 {
    728     uint8_t mbk;
    729     int update;
    730     int dct;
    731     CPUS390XState *env = &cpu->env;
    732 
    733     trace_ioinst("schm");
    734 
    735     if (SCHM_REG1_RES(reg1)) {
    736         s390_program_interrupt(env, PGM_OPERAND, ra);
    737         return;
    738     }
    739 
    740     mbk = SCHM_REG1_MBK(reg1);
    741     update = SCHM_REG1_UPD(reg1);
    742     dct = SCHM_REG1_DCT(reg1);
    743 
    744     if (update && (reg2 & 0x000000000000001f)) {
    745         s390_program_interrupt(env, PGM_OPERAND, ra);
    746         return;
    747     }
    748 
    749     css_do_schm(mbk, update, dct, update ? reg2 : 0);
    750 }
    751 
    752 void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
    753 {
    754     int cssid, ssid, schid, m;
    755     SubchDev *sch;
    756 
    757     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
    758         s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
    759         return;
    760     }
    761     trace_ioinst_sch_id("rsch", cssid, ssid, schid);
    762     sch = css_find_subch(m, cssid, ssid, schid);
    763     if (!sch || !css_subch_visible(sch)) {
    764         setcc(cpu, 3);
    765         return;
    766     }
    767     setcc(cpu, css_do_rsch(sch));
    768 }
    769 
    770 #define RCHP_REG1_RES(_reg) (_reg & 0x00000000ff00ff00)
    771 #define RCHP_REG1_CSSID(_reg) ((_reg & 0x0000000000ff0000) >> 16)
    772 #define RCHP_REG1_CHPID(_reg) (_reg & 0x00000000000000ff)
    773 void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
    774 {
    775     int cc;
    776     uint8_t cssid;
    777     uint8_t chpid;
    778     int ret;
    779     CPUS390XState *env = &cpu->env;
    780 
    781     if (RCHP_REG1_RES(reg1)) {
    782         s390_program_interrupt(env, PGM_OPERAND, ra);
    783         return;
    784     }
    785 
    786     cssid = RCHP_REG1_CSSID(reg1);
    787     chpid = RCHP_REG1_CHPID(reg1);
    788 
    789     trace_ioinst_chp_id("rchp", cssid, chpid);
    790 
    791     ret = css_do_rchp(cssid, chpid);
    792 
    793     switch (ret) {
    794     case -ENODEV:
    795         cc = 3;
    796         break;
    797     case -EBUSY:
    798         cc = 2;
    799         break;
    800     case 0:
    801         cc = 0;
    802         break;
    803     default:
    804         /* Invalid channel subsystem. */
    805         s390_program_interrupt(env, PGM_OPERAND, ra);
    806         return;
    807     }
    808     setcc(cpu, cc);
    809 }
    810 
    811 #define SAL_REG1_INVALID(_reg) (_reg & 0x0000000080000000)
    812 void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
    813 {
    814     /* We do not provide address limit checking, so let's suppress it. */
    815     if (SAL_REG1_INVALID(reg1) || reg1 & 0x000000000000ffff) {
    816         s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
    817     }
    818 }