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 CONFIG_DEVICES /* CONFIG_IOMMUFD */ 19 #include <linux/vfio.h> 20 #include <linux/vfio_ccw.h> 21 #include <sys/ioctl.h> 22 23 #include "qapi/error.h" 24 #include "hw/vfio/vfio-common.h" 25 #include "sysemu/iommufd.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 VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data); 81 struct ccw_io_region *region = vcdev->io_region; 82 int ret; 83 84 if (!(sch->orb.ctrl0 & ORB_CTRL0_MASK_PFCH) && vcdev->force_orb_pfch) { 85 sch->orb.ctrl0 |= ORB_CTRL0_MASK_PFCH; 86 warn_once_pfch(vcdev, sch, "PFCH flag forced"); 87 } 88 89 QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB)); 90 QEMU_BUILD_BUG_ON(sizeof(region->scsw_area) != sizeof(SCSW)); 91 QEMU_BUILD_BUG_ON(sizeof(region->irb_area) != sizeof(IRB)); 92 93 memset(region, 0, sizeof(*region)); 94 95 memcpy(region->orb_area, &sch->orb, sizeof(ORB)); 96 memcpy(region->scsw_area, &sch->curr_status.scsw, sizeof(SCSW)); 97 98 again: 99 ret = pwrite(vcdev->vdev.fd, region, 100 vcdev->io_region_size, vcdev->io_region_offset); 101 if (ret != vcdev->io_region_size) { 102 if (errno == EAGAIN) { 103 goto again; 104 } 105 error_report("vfio-ccw: write I/O region failed with errno=%d", errno); 106 ret = errno ? -errno : -EFAULT; 107 } else { 108 ret = 0; 109 } 110 switch (ret) { 111 case 0: 112 return IOINST_CC_EXPECTED; 113 case -EBUSY: 114 return IOINST_CC_BUSY; 115 case -ENODEV: 116 case -EACCES: 117 return IOINST_CC_NOT_OPERATIONAL; 118 case -EFAULT: 119 default: 120 sch_gen_unit_exception(sch); 121 css_inject_io_interrupt(sch); 122 return IOINST_CC_EXPECTED; 123 } 124 } 125 126 static IOInstEnding vfio_ccw_handle_store(SubchDev *sch) 127 { 128 VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data); 129 SCHIB *schib = &sch->curr_status; 130 struct ccw_schib_region *region = vcdev->schib_region; 131 SCHIB *s; 132 int ret; 133 134 /* schib region not available so nothing else to do */ 135 if (!region) { 136 return IOINST_CC_EXPECTED; 137 } 138 139 memset(region, 0, sizeof(*region)); 140 ret = pread(vcdev->vdev.fd, region, vcdev->schib_region_size, 141 vcdev->schib_region_offset); 142 143 if (ret == -1) { 144 /* 145 * Device is probably damaged, but store subchannel does not 146 * have a nonzero cc defined for this scenario. Log an error, 147 * and presume things are otherwise fine. 148 */ 149 error_report("vfio-ccw: store region read failed with errno=%d", errno); 150 return IOINST_CC_EXPECTED; 151 } 152 153 /* 154 * Selectively copy path-related bits of the SCHIB, 155 * rather than copying the entire struct. 156 */ 157 s = (SCHIB *)region->schib_area; 158 schib->pmcw.pnom = s->pmcw.pnom; 159 schib->pmcw.lpum = s->pmcw.lpum; 160 schib->pmcw.pam = s->pmcw.pam; 161 schib->pmcw.pom = s->pmcw.pom; 162 163 if (s->scsw.flags & SCSW_FLAGS_MASK_PNO) { 164 schib->scsw.flags |= SCSW_FLAGS_MASK_PNO; 165 } 166 167 return IOINST_CC_EXPECTED; 168 } 169 170 static int vfio_ccw_handle_clear(SubchDev *sch) 171 { 172 VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data); 173 struct ccw_cmd_region *region = vcdev->async_cmd_region; 174 int ret; 175 176 if (!vcdev->async_cmd_region) { 177 /* Async command region not available, fall back to emulation */ 178 return -ENOSYS; 179 } 180 181 memset(region, 0, sizeof(*region)); 182 region->command = VFIO_CCW_ASYNC_CMD_CSCH; 183 184 again: 185 ret = pwrite(vcdev->vdev.fd, region, 186 vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset); 187 if (ret != vcdev->async_cmd_region_size) { 188 if (errno == EAGAIN) { 189 goto again; 190 } 191 error_report("vfio-ccw: write cmd region failed with errno=%d", errno); 192 ret = errno ? -errno : -EFAULT; 193 } else { 194 ret = 0; 195 } 196 switch (ret) { 197 case 0: 198 case -ENODEV: 199 case -EACCES: 200 return ret; 201 case -EFAULT: 202 default: 203 sch_gen_unit_exception(sch); 204 css_inject_io_interrupt(sch); 205 return 0; 206 } 207 } 208 209 static int vfio_ccw_handle_halt(SubchDev *sch) 210 { 211 VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data); 212 struct ccw_cmd_region *region = vcdev->async_cmd_region; 213 int ret; 214 215 if (!vcdev->async_cmd_region) { 216 /* Async command region not available, fall back to emulation */ 217 return -ENOSYS; 218 } 219 220 memset(region, 0, sizeof(*region)); 221 region->command = VFIO_CCW_ASYNC_CMD_HSCH; 222 223 again: 224 ret = pwrite(vcdev->vdev.fd, region, 225 vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset); 226 if (ret != vcdev->async_cmd_region_size) { 227 if (errno == EAGAIN) { 228 goto again; 229 } 230 error_report("vfio-ccw: write cmd region failed with errno=%d", errno); 231 ret = errno ? -errno : -EFAULT; 232 } else { 233 ret = 0; 234 } 235 switch (ret) { 236 case 0: 237 case -EBUSY: 238 case -ENODEV: 239 case -EACCES: 240 return ret; 241 case -EFAULT: 242 default: 243 sch_gen_unit_exception(sch); 244 css_inject_io_interrupt(sch); 245 return 0; 246 } 247 } 248 249 static void vfio_ccw_reset(DeviceState *dev) 250 { 251 VFIOCCWDevice *vcdev = VFIO_CCW(dev); 252 253 ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET); 254 } 255 256 static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev) 257 { 258 struct ccw_crw_region *region = vcdev->crw_region; 259 CRW crw; 260 int size; 261 262 /* Keep reading CRWs as long as data is returned */ 263 do { 264 memset(region, 0, sizeof(*region)); 265 size = pread(vcdev->vdev.fd, region, vcdev->crw_region_size, 266 vcdev->crw_region_offset); 267 268 if (size == -1) { 269 error_report("vfio-ccw: Read crw region failed with errno=%d", 270 errno); 271 break; 272 } 273 274 if (region->crw == 0) { 275 /* No more CRWs to queue */ 276 break; 277 } 278 279 memcpy(&crw, ®ion->crw, sizeof(CRW)); 280 281 css_crw_add_to_queue(crw); 282 } while (1); 283 } 284 285 static void vfio_ccw_req_notifier_handler(void *opaque) 286 { 287 VFIOCCWDevice *vcdev = opaque; 288 Error *err = NULL; 289 290 if (!event_notifier_test_and_clear(&vcdev->req_notifier)) { 291 return; 292 } 293 294 qdev_unplug(DEVICE(vcdev), &err); 295 if (err) { 296 warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name); 297 } 298 } 299 300 static void vfio_ccw_crw_notifier_handler(void *opaque) 301 { 302 VFIOCCWDevice *vcdev = opaque; 303 304 while (event_notifier_test_and_clear(&vcdev->crw_notifier)) { 305 vfio_ccw_crw_read(vcdev); 306 } 307 } 308 309 static void vfio_ccw_io_notifier_handler(void *opaque) 310 { 311 VFIOCCWDevice *vcdev = opaque; 312 struct ccw_io_region *region = vcdev->io_region; 313 CcwDevice *ccw_dev = CCW_DEVICE(vcdev); 314 SubchDev *sch = ccw_dev->sch; 315 SCHIB *schib = &sch->curr_status; 316 SCSW s; 317 IRB irb; 318 ESW esw; 319 int size; 320 321 if (!event_notifier_test_and_clear(&vcdev->io_notifier)) { 322 return; 323 } 324 325 size = pread(vcdev->vdev.fd, region, vcdev->io_region_size, 326 vcdev->io_region_offset); 327 if (size == -1) { 328 switch (errno) { 329 case ENODEV: 330 /* Generate a deferred cc 3 condition. */ 331 schib->scsw.flags |= SCSW_FLAGS_MASK_CC; 332 schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL; 333 schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND); 334 goto read_err; 335 case EFAULT: 336 /* Memory problem, generate channel data check. */ 337 schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND; 338 schib->scsw.cstat = SCSW_CSTAT_DATA_CHECK; 339 schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL; 340 schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | 341 SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; 342 goto read_err; 343 default: 344 /* Error, generate channel program check. */ 345 schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND; 346 schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK; 347 schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL; 348 schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | 349 SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; 350 goto read_err; 351 } 352 } else if (size != vcdev->io_region_size) { 353 /* Information transfer error, generate channel-control check. */ 354 schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND; 355 schib->scsw.cstat = SCSW_CSTAT_CHN_CTRL_CHK; 356 schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL; 357 schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | 358 SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; 359 goto read_err; 360 } 361 362 memcpy(&irb, region->irb_area, sizeof(IRB)); 363 364 /* Update control block via irb. */ 365 s = schib->scsw; 366 copy_scsw_to_guest(&s, &irb.scsw); 367 schib->scsw = s; 368 369 copy_esw_to_guest(&esw, &irb.esw); 370 sch->esw = esw; 371 372 /* If a uint check is pending, copy sense data. */ 373 if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) && 374 (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) { 375 memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw)); 376 } 377 378 read_err: 379 css_inject_io_interrupt(sch); 380 } 381 382 static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev, 383 unsigned int irq, 384 Error **errp) 385 { 386 VFIODevice *vdev = &vcdev->vdev; 387 g_autofree struct vfio_irq_info *irq_info = NULL; 388 size_t argsz; 389 int fd; 390 EventNotifier *notifier; 391 IOHandler *fd_read; 392 393 switch (irq) { 394 case VFIO_CCW_IO_IRQ_INDEX: 395 notifier = &vcdev->io_notifier; 396 fd_read = vfio_ccw_io_notifier_handler; 397 break; 398 case VFIO_CCW_CRW_IRQ_INDEX: 399 notifier = &vcdev->crw_notifier; 400 fd_read = vfio_ccw_crw_notifier_handler; 401 break; 402 case VFIO_CCW_REQ_IRQ_INDEX: 403 notifier = &vcdev->req_notifier; 404 fd_read = vfio_ccw_req_notifier_handler; 405 break; 406 default: 407 error_setg(errp, "vfio: Unsupported device irq(%d)", irq); 408 return false; 409 } 410 411 if (vdev->num_irqs < irq + 1) { 412 error_setg(errp, "vfio: IRQ %u not available (number of irqs %u)", 413 irq, vdev->num_irqs); 414 return false; 415 } 416 417 argsz = sizeof(*irq_info); 418 irq_info = g_malloc0(argsz); 419 irq_info->index = irq; 420 irq_info->argsz = argsz; 421 if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, 422 irq_info) < 0 || irq_info->count < 1) { 423 error_setg_errno(errp, errno, "vfio: Error getting irq info"); 424 return false; 425 } 426 427 if (event_notifier_init(notifier, 0)) { 428 error_setg_errno(errp, errno, 429 "vfio: Unable to init event notifier for irq (%d)", 430 irq); 431 return false; 432 } 433 434 fd = event_notifier_get_fd(notifier); 435 qemu_set_fd_handler(fd, fd_read, NULL, vcdev); 436 437 if (!vfio_set_irq_signaling(vdev, irq, 0, 438 VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) { 439 qemu_set_fd_handler(fd, NULL, NULL, vcdev); 440 event_notifier_cleanup(notifier); 441 } 442 443 return true; 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 bool 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 false; 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 false; 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 false; 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 true; 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 false; 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 583 /* Call the class init function for subchannel. */ 584 if (cdc->realize) { 585 cdc->realize(cdev, vcdev->vdev.sysfsdev, &err); 586 if (err) { 587 goto out_err_propagate; 588 } 589 } 590 591 if (!vfio_device_get_name(vbasedev, errp)) { 592 return; 593 } 594 595 if (!vfio_attach_device(cdev->mdevid, vbasedev, 596 &address_space_memory, errp)) { 597 goto out_attach_dev_err; 598 } 599 600 if (!vfio_ccw_get_region(vcdev, &err)) { 601 goto out_region_err; 602 } 603 604 if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err)) { 605 goto out_io_notifier_err; 606 } 607 608 if (vcdev->crw_region) { 609 if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, 610 &err)) { 611 goto out_irq_notifier_err; 612 } 613 } 614 615 if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err)) { 616 /* 617 * Report this error, but do not make it a failing condition. 618 * Lack of this IRQ in the host does not prevent normal operation. 619 */ 620 error_report_err(err); 621 } 622 623 return; 624 625 out_irq_notifier_err: 626 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX); 627 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); 628 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); 629 out_io_notifier_err: 630 vfio_ccw_put_region(vcdev); 631 out_region_err: 632 vfio_detach_device(vbasedev); 633 out_attach_dev_err: 634 g_free(vbasedev->name); 635 if (cdc->unrealize) { 636 cdc->unrealize(cdev); 637 } 638 out_err_propagate: 639 error_propagate(errp, err); 640 } 641 642 static void vfio_ccw_unrealize(DeviceState *dev) 643 { 644 S390CCWDevice *cdev = S390_CCW_DEVICE(dev); 645 VFIOCCWDevice *vcdev = VFIO_CCW(cdev); 646 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev); 647 648 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX); 649 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); 650 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); 651 vfio_ccw_put_region(vcdev); 652 vfio_detach_device(&vcdev->vdev); 653 g_free(vcdev->vdev.name); 654 655 if (cdc->unrealize) { 656 cdc->unrealize(cdev); 657 } 658 } 659 660 static Property vfio_ccw_properties[] = { 661 DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev), 662 DEFINE_PROP_BOOL("force-orb-pfch", VFIOCCWDevice, force_orb_pfch, false), 663 #ifdef CONFIG_IOMMUFD 664 DEFINE_PROP_LINK("iommufd", VFIOCCWDevice, vdev.iommufd, 665 TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *), 666 #endif 667 DEFINE_PROP_END_OF_LIST(), 668 }; 669 670 static const VMStateDescription vfio_ccw_vmstate = { 671 .name = "vfio-ccw", 672 .unmigratable = 1, 673 }; 674 675 static void vfio_ccw_instance_init(Object *obj) 676 { 677 VFIOCCWDevice *vcdev = VFIO_CCW(obj); 678 VFIODevice *vbasedev = &vcdev->vdev; 679 680 /* 681 * All vfio-ccw devices are believed to operate in a way compatible with 682 * discarding of memory in RAM blocks, ie. pages pinned in the host are 683 * in the current working set of the guest driver and therefore never 684 * overlap e.g., with pages available to the guest balloon driver. This 685 * needs to be set before vfio_get_device() for vfio common to handle 686 * ram_block_discard_disable(). 687 */ 688 vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_CCW, &vfio_ccw_ops, 689 DEVICE(vcdev), true); 690 } 691 692 #ifdef CONFIG_IOMMUFD 693 static void vfio_ccw_set_fd(Object *obj, const char *str, Error **errp) 694 { 695 vfio_device_set_fd(&VFIO_CCW(obj)->vdev, str, errp); 696 } 697 #endif 698 699 static void vfio_ccw_class_init(ObjectClass *klass, void *data) 700 { 701 DeviceClass *dc = DEVICE_CLASS(klass); 702 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass); 703 704 device_class_set_props(dc, vfio_ccw_properties); 705 #ifdef CONFIG_IOMMUFD 706 object_class_property_add_str(klass, "fd", NULL, vfio_ccw_set_fd); 707 #endif 708 dc->vmsd = &vfio_ccw_vmstate; 709 dc->desc = "VFIO-based subchannel assignment"; 710 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 711 dc->realize = vfio_ccw_realize; 712 dc->unrealize = vfio_ccw_unrealize; 713 dc->reset = vfio_ccw_reset; 714 715 cdc->handle_request = vfio_ccw_handle_request; 716 cdc->handle_halt = vfio_ccw_handle_halt; 717 cdc->handle_clear = vfio_ccw_handle_clear; 718 cdc->handle_store = vfio_ccw_handle_store; 719 } 720 721 static const TypeInfo vfio_ccw_info = { 722 .name = TYPE_VFIO_CCW, 723 .parent = TYPE_S390_CCW, 724 .instance_size = sizeof(VFIOCCWDevice), 725 .instance_init = vfio_ccw_instance_init, 726 .class_init = vfio_ccw_class_init, 727 }; 728 729 static void register_vfio_ccw_type(void) 730 { 731 type_register_static(&vfio_ccw_info); 732 } 733 734 type_init(register_vfio_ccw_type) 735