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