1 /* 2 * vfio based subchannel assignment support 3 * 4 * Copyright 2017 IBM Corp. 5 * Copyright 2019 Red Hat, Inc. 6 * 7 * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 8 * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 9 * Pierre Morel <pmorel@linux.vnet.ibm.com> 10 * Cornelia Huck <cohuck@redhat.com> 11 * 12 * This work is licensed under the terms of the GNU GPL, version 2 or (at 13 * your option) any later version. See the COPYING file in the top-level 14 * directory. 15 */ 16 17 #include "qemu/osdep.h" 18 #include <linux/vfio.h> 19 #include <linux/vfio_ccw.h> 20 #include <sys/ioctl.h> 21 22 #include "qapi/error.h" 23 #include "hw/sysbus.h" 24 #include "hw/vfio/vfio.h" 25 #include "hw/vfio/vfio-common.h" 26 #include "hw/s390x/s390-ccw.h" 27 #include "hw/s390x/vfio-ccw.h" 28 #include "hw/qdev-properties.h" 29 #include "hw/s390x/ccw-device.h" 30 #include "exec/address-spaces.h" 31 #include "qemu/error-report.h" 32 #include "qemu/main-loop.h" 33 #include "qemu/module.h" 34 35 struct VFIOCCWDevice { 36 S390CCWDevice cdev; 37 VFIODevice vdev; 38 uint64_t io_region_size; 39 uint64_t io_region_offset; 40 struct ccw_io_region *io_region; 41 uint64_t async_cmd_region_size; 42 uint64_t async_cmd_region_offset; 43 struct ccw_cmd_region *async_cmd_region; 44 uint64_t schib_region_size; 45 uint64_t schib_region_offset; 46 struct ccw_schib_region *schib_region; 47 uint64_t crw_region_size; 48 uint64_t crw_region_offset; 49 struct ccw_crw_region *crw_region; 50 EventNotifier io_notifier; 51 EventNotifier crw_notifier; 52 EventNotifier req_notifier; 53 bool force_orb_pfch; 54 bool warned_orb_pfch; 55 }; 56 57 static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch, 58 const char *msg) 59 { 60 warn_report_once_cond(&vcdev->warned_orb_pfch, 61 "vfio-ccw (devno %x.%x.%04x): %s", 62 sch->cssid, sch->ssid, sch->devno, msg); 63 } 64 65 static void vfio_ccw_compute_needs_reset(VFIODevice *vdev) 66 { 67 vdev->needs_reset = false; 68 } 69 70 /* 71 * We don't need vfio_hot_reset_multi and vfio_eoi operations for 72 * vfio_ccw device now. 73 */ 74 struct VFIODeviceOps vfio_ccw_ops = { 75 .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset, 76 }; 77 78 static IOInstEnding vfio_ccw_handle_request(SubchDev *sch) 79 { 80 S390CCWDevice *cdev = sch->driver_data; 81 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 82 struct ccw_io_region *region = vcdev->io_region; 83 int ret; 84 85 if (!(sch->orb.ctrl0 & ORB_CTRL0_MASK_PFCH) && vcdev->force_orb_pfch) { 86 sch->orb.ctrl0 |= ORB_CTRL0_MASK_PFCH; 87 warn_once_pfch(vcdev, sch, "PFCH flag forced"); 88 } 89 90 QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB)); 91 QEMU_BUILD_BUG_ON(sizeof(region->scsw_area) != sizeof(SCSW)); 92 QEMU_BUILD_BUG_ON(sizeof(region->irb_area) != sizeof(IRB)); 93 94 memset(region, 0, sizeof(*region)); 95 96 memcpy(region->orb_area, &sch->orb, sizeof(ORB)); 97 memcpy(region->scsw_area, &sch->curr_status.scsw, sizeof(SCSW)); 98 99 again: 100 ret = pwrite(vcdev->vdev.fd, region, 101 vcdev->io_region_size, vcdev->io_region_offset); 102 if (ret != vcdev->io_region_size) { 103 if (errno == EAGAIN) { 104 goto again; 105 } 106 error_report("vfio-ccw: write I/O region failed with errno=%d", errno); 107 ret = -errno; 108 } else { 109 ret = region->ret_code; 110 } 111 switch (ret) { 112 case 0: 113 return IOINST_CC_EXPECTED; 114 case -EBUSY: 115 return IOINST_CC_BUSY; 116 case -ENODEV: 117 case -EACCES: 118 return IOINST_CC_NOT_OPERATIONAL; 119 case -EFAULT: 120 default: 121 sch_gen_unit_exception(sch); 122 css_inject_io_interrupt(sch); 123 return IOINST_CC_EXPECTED; 124 } 125 } 126 127 static IOInstEnding vfio_ccw_handle_store(SubchDev *sch) 128 { 129 S390CCWDevice *cdev = sch->driver_data; 130 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 131 SCHIB *schib = &sch->curr_status; 132 struct ccw_schib_region *region = vcdev->schib_region; 133 SCHIB *s; 134 int ret; 135 136 /* schib region not available so nothing else to do */ 137 if (!region) { 138 return IOINST_CC_EXPECTED; 139 } 140 141 memset(region, 0, sizeof(*region)); 142 ret = pread(vcdev->vdev.fd, region, vcdev->schib_region_size, 143 vcdev->schib_region_offset); 144 145 if (ret == -1) { 146 /* 147 * Device is probably damaged, but store subchannel does not 148 * have a nonzero cc defined for this scenario. Log an error, 149 * and presume things are otherwise fine. 150 */ 151 error_report("vfio-ccw: store region read failed with errno=%d", errno); 152 return IOINST_CC_EXPECTED; 153 } 154 155 /* 156 * Selectively copy path-related bits of the SCHIB, 157 * rather than copying the entire struct. 158 */ 159 s = (SCHIB *)region->schib_area; 160 schib->pmcw.pnom = s->pmcw.pnom; 161 schib->pmcw.lpum = s->pmcw.lpum; 162 schib->pmcw.pam = s->pmcw.pam; 163 schib->pmcw.pom = s->pmcw.pom; 164 165 if (s->scsw.flags & SCSW_FLAGS_MASK_PNO) { 166 schib->scsw.flags |= SCSW_FLAGS_MASK_PNO; 167 } 168 169 return IOINST_CC_EXPECTED; 170 } 171 172 static int vfio_ccw_handle_clear(SubchDev *sch) 173 { 174 S390CCWDevice *cdev = sch->driver_data; 175 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 176 struct ccw_cmd_region *region = vcdev->async_cmd_region; 177 int ret; 178 179 if (!vcdev->async_cmd_region) { 180 /* Async command region not available, fall back to emulation */ 181 return -ENOSYS; 182 } 183 184 memset(region, 0, sizeof(*region)); 185 region->command = VFIO_CCW_ASYNC_CMD_CSCH; 186 187 again: 188 ret = pwrite(vcdev->vdev.fd, region, 189 vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset); 190 if (ret != vcdev->async_cmd_region_size) { 191 if (errno == EAGAIN) { 192 goto again; 193 } 194 error_report("vfio-ccw: write cmd region failed with errno=%d", errno); 195 ret = -errno; 196 } else { 197 ret = region->ret_code; 198 } 199 switch (ret) { 200 case 0: 201 case -ENODEV: 202 case -EACCES: 203 return 0; 204 case -EFAULT: 205 default: 206 sch_gen_unit_exception(sch); 207 css_inject_io_interrupt(sch); 208 return 0; 209 } 210 } 211 212 static int vfio_ccw_handle_halt(SubchDev *sch) 213 { 214 S390CCWDevice *cdev = sch->driver_data; 215 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 216 struct ccw_cmd_region *region = vcdev->async_cmd_region; 217 int ret; 218 219 if (!vcdev->async_cmd_region) { 220 /* Async command region not available, fall back to emulation */ 221 return -ENOSYS; 222 } 223 224 memset(region, 0, sizeof(*region)); 225 region->command = VFIO_CCW_ASYNC_CMD_HSCH; 226 227 again: 228 ret = pwrite(vcdev->vdev.fd, region, 229 vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset); 230 if (ret != vcdev->async_cmd_region_size) { 231 if (errno == EAGAIN) { 232 goto again; 233 } 234 error_report("vfio-ccw: write cmd region failed with errno=%d", errno); 235 ret = -errno; 236 } else { 237 ret = region->ret_code; 238 } 239 switch (ret) { 240 case 0: 241 case -EBUSY: 242 case -ENODEV: 243 case -EACCES: 244 return 0; 245 case -EFAULT: 246 default: 247 sch_gen_unit_exception(sch); 248 css_inject_io_interrupt(sch); 249 return 0; 250 } 251 } 252 253 static void vfio_ccw_reset(DeviceState *dev) 254 { 255 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev); 256 S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev); 257 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 258 259 ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET); 260 } 261 262 static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev) 263 { 264 struct ccw_crw_region *region = vcdev->crw_region; 265 CRW crw; 266 int size; 267 268 /* Keep reading CRWs as long as data is returned */ 269 do { 270 memset(region, 0, sizeof(*region)); 271 size = pread(vcdev->vdev.fd, region, vcdev->crw_region_size, 272 vcdev->crw_region_offset); 273 274 if (size == -1) { 275 error_report("vfio-ccw: Read crw region failed with errno=%d", 276 errno); 277 break; 278 } 279 280 if (region->crw == 0) { 281 /* No more CRWs to queue */ 282 break; 283 } 284 285 memcpy(&crw, ®ion->crw, sizeof(CRW)); 286 287 css_crw_add_to_queue(crw); 288 } while (1); 289 } 290 291 static void vfio_ccw_req_notifier_handler(void *opaque) 292 { 293 VFIOCCWDevice *vcdev = opaque; 294 Error *err = NULL; 295 296 if (!event_notifier_test_and_clear(&vcdev->req_notifier)) { 297 return; 298 } 299 300 qdev_unplug(DEVICE(vcdev), &err); 301 if (err) { 302 warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name); 303 } 304 } 305 306 static void vfio_ccw_crw_notifier_handler(void *opaque) 307 { 308 VFIOCCWDevice *vcdev = opaque; 309 310 while (event_notifier_test_and_clear(&vcdev->crw_notifier)) { 311 vfio_ccw_crw_read(vcdev); 312 } 313 } 314 315 static void vfio_ccw_io_notifier_handler(void *opaque) 316 { 317 VFIOCCWDevice *vcdev = opaque; 318 struct ccw_io_region *region = vcdev->io_region; 319 S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev); 320 CcwDevice *ccw_dev = CCW_DEVICE(cdev); 321 SubchDev *sch = ccw_dev->sch; 322 SCHIB *schib = &sch->curr_status; 323 SCSW s; 324 IRB irb; 325 int size; 326 327 if (!event_notifier_test_and_clear(&vcdev->io_notifier)) { 328 return; 329 } 330 331 size = pread(vcdev->vdev.fd, region, vcdev->io_region_size, 332 vcdev->io_region_offset); 333 if (size == -1) { 334 switch (errno) { 335 case ENODEV: 336 /* Generate a deferred cc 3 condition. */ 337 schib->scsw.flags |= SCSW_FLAGS_MASK_CC; 338 schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL; 339 schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND); 340 goto read_err; 341 case EFAULT: 342 /* Memory problem, generate channel data check. */ 343 schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND; 344 schib->scsw.cstat = SCSW_CSTAT_DATA_CHECK; 345 schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL; 346 schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | 347 SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; 348 goto read_err; 349 default: 350 /* Error, generate channel program check. */ 351 schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND; 352 schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK; 353 schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL; 354 schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | 355 SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; 356 goto read_err; 357 } 358 } else if (size != vcdev->io_region_size) { 359 /* Information transfer error, generate channel-control check. */ 360 schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND; 361 schib->scsw.cstat = SCSW_CSTAT_CHN_CTRL_CHK; 362 schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL; 363 schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | 364 SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; 365 goto read_err; 366 } 367 368 memcpy(&irb, region->irb_area, sizeof(IRB)); 369 370 /* Update control block via irb. */ 371 s = schib->scsw; 372 copy_scsw_to_guest(&s, &irb.scsw); 373 schib->scsw = s; 374 375 /* If a uint check is pending, copy sense data. */ 376 if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) && 377 (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) { 378 memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw)); 379 } 380 381 read_err: 382 css_inject_io_interrupt(sch); 383 } 384 385 static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev, 386 unsigned int irq, 387 Error **errp) 388 { 389 VFIODevice *vdev = &vcdev->vdev; 390 struct vfio_irq_info *irq_info; 391 size_t argsz; 392 int fd; 393 EventNotifier *notifier; 394 IOHandler *fd_read; 395 396 switch (irq) { 397 case VFIO_CCW_IO_IRQ_INDEX: 398 notifier = &vcdev->io_notifier; 399 fd_read = vfio_ccw_io_notifier_handler; 400 break; 401 case VFIO_CCW_CRW_IRQ_INDEX: 402 notifier = &vcdev->crw_notifier; 403 fd_read = vfio_ccw_crw_notifier_handler; 404 break; 405 case VFIO_CCW_REQ_IRQ_INDEX: 406 notifier = &vcdev->req_notifier; 407 fd_read = vfio_ccw_req_notifier_handler; 408 break; 409 default: 410 error_setg(errp, "vfio: Unsupported device irq(%d)", irq); 411 return; 412 } 413 414 if (vdev->num_irqs < irq + 1) { 415 error_setg(errp, "vfio: unexpected number of irqs %u", 416 vdev->num_irqs); 417 return; 418 } 419 420 argsz = sizeof(*irq_info); 421 irq_info = g_malloc0(argsz); 422 irq_info->index = irq; 423 irq_info->argsz = argsz; 424 if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, 425 irq_info) < 0 || irq_info->count < 1) { 426 error_setg_errno(errp, errno, "vfio: Error getting irq info"); 427 goto out_free_info; 428 } 429 430 if (event_notifier_init(notifier, 0)) { 431 error_setg_errno(errp, errno, 432 "vfio: Unable to init event notifier for irq (%d)", 433 irq); 434 goto out_free_info; 435 } 436 437 fd = event_notifier_get_fd(notifier); 438 qemu_set_fd_handler(fd, fd_read, NULL, vcdev); 439 440 if (vfio_set_irq_signaling(vdev, irq, 0, 441 VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) { 442 qemu_set_fd_handler(fd, NULL, NULL, vcdev); 443 event_notifier_cleanup(notifier); 444 } 445 446 out_free_info: 447 g_free(irq_info); 448 } 449 450 static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev, 451 unsigned int irq) 452 { 453 Error *err = NULL; 454 EventNotifier *notifier; 455 456 switch (irq) { 457 case VFIO_CCW_IO_IRQ_INDEX: 458 notifier = &vcdev->io_notifier; 459 break; 460 case VFIO_CCW_CRW_IRQ_INDEX: 461 notifier = &vcdev->crw_notifier; 462 break; 463 case VFIO_CCW_REQ_IRQ_INDEX: 464 notifier = &vcdev->req_notifier; 465 break; 466 default: 467 error_report("vfio: Unsupported device irq(%d)", irq); 468 return; 469 } 470 471 if (vfio_set_irq_signaling(&vcdev->vdev, irq, 0, 472 VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { 473 error_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name); 474 } 475 476 qemu_set_fd_handler(event_notifier_get_fd(notifier), 477 NULL, NULL, vcdev); 478 event_notifier_cleanup(notifier); 479 } 480 481 static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp) 482 { 483 VFIODevice *vdev = &vcdev->vdev; 484 struct vfio_region_info *info; 485 int ret; 486 487 /* Sanity check device */ 488 if (!(vdev->flags & VFIO_DEVICE_FLAGS_CCW)) { 489 error_setg(errp, "vfio: Um, this isn't a vfio-ccw device"); 490 return; 491 } 492 493 /* 494 * We always expect at least the I/O region to be present. We also 495 * may have a variable number of regions governed by capabilities. 496 */ 497 if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) { 498 error_setg(errp, "vfio: too few regions (%u), expected at least %u", 499 vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1); 500 return; 501 } 502 503 ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, &info); 504 if (ret) { 505 error_setg_errno(errp, -ret, "vfio: Error getting config info"); 506 return; 507 } 508 509 vcdev->io_region_size = info->size; 510 if (sizeof(*vcdev->io_region) != vcdev->io_region_size) { 511 error_setg(errp, "vfio: Unexpected size of the I/O region"); 512 goto out_err; 513 } 514 515 vcdev->io_region_offset = info->offset; 516 vcdev->io_region = g_malloc0(info->size); 517 g_free(info); 518 519 /* check for the optional async command region */ 520 ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW, 521 VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD, &info); 522 if (!ret) { 523 vcdev->async_cmd_region_size = info->size; 524 if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) { 525 error_setg(errp, "vfio: Unexpected size of the async cmd region"); 526 goto out_err; 527 } 528 vcdev->async_cmd_region_offset = info->offset; 529 vcdev->async_cmd_region = g_malloc0(info->size); 530 g_free(info); 531 } 532 533 ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW, 534 VFIO_REGION_SUBTYPE_CCW_SCHIB, &info); 535 if (!ret) { 536 vcdev->schib_region_size = info->size; 537 if (sizeof(*vcdev->schib_region) != vcdev->schib_region_size) { 538 error_setg(errp, "vfio: Unexpected size of the schib region"); 539 goto out_err; 540 } 541 vcdev->schib_region_offset = info->offset; 542 vcdev->schib_region = g_malloc(info->size); 543 g_free(info); 544 } 545 546 ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW, 547 VFIO_REGION_SUBTYPE_CCW_CRW, &info); 548 549 if (!ret) { 550 vcdev->crw_region_size = info->size; 551 if (sizeof(*vcdev->crw_region) != vcdev->crw_region_size) { 552 error_setg(errp, "vfio: Unexpected size of the CRW region"); 553 goto out_err; 554 } 555 vcdev->crw_region_offset = info->offset; 556 vcdev->crw_region = g_malloc(info->size); 557 g_free(info); 558 } 559 560 return; 561 562 out_err: 563 g_free(vcdev->crw_region); 564 g_free(vcdev->schib_region); 565 g_free(vcdev->async_cmd_region); 566 g_free(vcdev->io_region); 567 g_free(info); 568 return; 569 } 570 571 static void vfio_ccw_put_region(VFIOCCWDevice *vcdev) 572 { 573 g_free(vcdev->crw_region); 574 g_free(vcdev->schib_region); 575 g_free(vcdev->async_cmd_region); 576 g_free(vcdev->io_region); 577 } 578 579 static void vfio_ccw_put_device(VFIOCCWDevice *vcdev) 580 { 581 g_free(vcdev->vdev.name); 582 vfio_put_base_device(&vcdev->vdev); 583 } 584 585 static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev, 586 Error **errp) 587 { 588 char *name = g_strdup_printf("%x.%x.%04x", vcdev->cdev.hostid.cssid, 589 vcdev->cdev.hostid.ssid, 590 vcdev->cdev.hostid.devid); 591 VFIODevice *vbasedev; 592 593 QLIST_FOREACH(vbasedev, &group->device_list, next) { 594 if (strcmp(vbasedev->name, name) == 0) { 595 error_setg(errp, "vfio: subchannel %s has already been attached", 596 name); 597 goto out_err; 598 } 599 } 600 601 /* 602 * All vfio-ccw devices are believed to operate in a way compatible with 603 * discarding of memory in RAM blocks, ie. pages pinned in the host are 604 * in the current working set of the guest driver and therefore never 605 * overlap e.g., with pages available to the guest balloon driver. This 606 * needs to be set before vfio_get_device() for vfio common to handle 607 * ram_block_discard_disable(). 608 */ 609 vcdev->vdev.ram_block_discard_allowed = true; 610 611 if (vfio_get_device(group, vcdev->cdev.mdevid, &vcdev->vdev, errp)) { 612 goto out_err; 613 } 614 615 vcdev->vdev.ops = &vfio_ccw_ops; 616 vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW; 617 vcdev->vdev.name = name; 618 vcdev->vdev.dev = &vcdev->cdev.parent_obj.parent_obj; 619 620 return; 621 622 out_err: 623 g_free(name); 624 } 625 626 static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, Error **errp) 627 { 628 char *tmp, group_path[PATH_MAX]; 629 ssize_t len; 630 int groupid; 631 632 tmp = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/%s/iommu_group", 633 cdev->hostid.cssid, cdev->hostid.ssid, 634 cdev->hostid.devid, cdev->mdevid); 635 len = readlink(tmp, group_path, sizeof(group_path)); 636 g_free(tmp); 637 638 if (len <= 0 || len >= sizeof(group_path)) { 639 error_setg(errp, "vfio: no iommu_group found"); 640 return NULL; 641 } 642 643 group_path[len] = 0; 644 645 if (sscanf(basename(group_path), "%d", &groupid) != 1) { 646 error_setg(errp, "vfio: failed to read %s", group_path); 647 return NULL; 648 } 649 650 return vfio_get_group(groupid, &address_space_memory, errp); 651 } 652 653 static void vfio_ccw_realize(DeviceState *dev, Error **errp) 654 { 655 VFIOGroup *group; 656 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev); 657 S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev); 658 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 659 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev); 660 Error *err = NULL; 661 662 /* Call the class init function for subchannel. */ 663 if (cdc->realize) { 664 cdc->realize(cdev, vcdev->vdev.sysfsdev, &err); 665 if (err) { 666 goto out_err_propagate; 667 } 668 } 669 670 group = vfio_ccw_get_group(cdev, &err); 671 if (!group) { 672 goto out_group_err; 673 } 674 675 vfio_ccw_get_device(group, vcdev, &err); 676 if (err) { 677 goto out_device_err; 678 } 679 680 vfio_ccw_get_region(vcdev, &err); 681 if (err) { 682 goto out_region_err; 683 } 684 685 vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err); 686 if (err) { 687 goto out_io_notifier_err; 688 } 689 690 if (vcdev->crw_region) { 691 vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, &err); 692 if (err) { 693 goto out_crw_notifier_err; 694 } 695 } 696 697 vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err); 698 if (err) { 699 goto out_req_notifier_err; 700 } 701 702 return; 703 704 out_req_notifier_err: 705 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); 706 out_crw_notifier_err: 707 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); 708 out_io_notifier_err: 709 vfio_ccw_put_region(vcdev); 710 out_region_err: 711 vfio_ccw_put_device(vcdev); 712 out_device_err: 713 vfio_put_group(group); 714 out_group_err: 715 if (cdc->unrealize) { 716 cdc->unrealize(cdev); 717 } 718 out_err_propagate: 719 error_propagate(errp, err); 720 } 721 722 static void vfio_ccw_unrealize(DeviceState *dev) 723 { 724 CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev); 725 S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev); 726 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 727 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev); 728 VFIOGroup *group = vcdev->vdev.group; 729 730 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX); 731 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); 732 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); 733 vfio_ccw_put_region(vcdev); 734 vfio_ccw_put_device(vcdev); 735 vfio_put_group(group); 736 737 if (cdc->unrealize) { 738 cdc->unrealize(cdev); 739 } 740 } 741 742 static Property vfio_ccw_properties[] = { 743 DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev), 744 DEFINE_PROP_BOOL("force-orb-pfch", VFIOCCWDevice, force_orb_pfch, false), 745 DEFINE_PROP_END_OF_LIST(), 746 }; 747 748 static const VMStateDescription vfio_ccw_vmstate = { 749 .name = "vfio-ccw", 750 .unmigratable = 1, 751 }; 752 753 static void vfio_ccw_class_init(ObjectClass *klass, void *data) 754 { 755 DeviceClass *dc = DEVICE_CLASS(klass); 756 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass); 757 758 device_class_set_props(dc, vfio_ccw_properties); 759 dc->vmsd = &vfio_ccw_vmstate; 760 dc->desc = "VFIO-based subchannel assignment"; 761 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 762 dc->realize = vfio_ccw_realize; 763 dc->unrealize = vfio_ccw_unrealize; 764 dc->reset = vfio_ccw_reset; 765 766 cdc->handle_request = vfio_ccw_handle_request; 767 cdc->handle_halt = vfio_ccw_handle_halt; 768 cdc->handle_clear = vfio_ccw_handle_clear; 769 cdc->handle_store = vfio_ccw_handle_store; 770 } 771 772 static const TypeInfo vfio_ccw_info = { 773 .name = TYPE_VFIO_CCW, 774 .parent = TYPE_S390_CCW, 775 .instance_size = sizeof(VFIOCCWDevice), 776 .class_init = vfio_ccw_class_init, 777 }; 778 779 static void register_vfio_ccw_type(void) 780 { 781 type_register_static(&vfio_ccw_info); 782 } 783 784 type_init(register_vfio_ccw_type) 785