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