ccw.c (2a3b9cbaa7b25a4db4cdcfe1c65279c5464f2923) | ccw.c (46ea3841edaff2a7657b8f6c7f474e5e3850cd62) |
---|---|
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> --- 27 unchanged lines hidden (view full) --- 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; | 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> --- 27 unchanged lines hidden (view full) --- 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; |
|
44 EventNotifier io_notifier; 45 bool force_orb_pfch; 46 bool warned_orb_pfch; 47}; 48 49static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch, 50 const char *msg) 51{ --- 59 unchanged lines hidden (view full) --- 111 case -EFAULT: 112 default: 113 sch_gen_unit_exception(sch); 114 css_inject_io_interrupt(sch); 115 return IOINST_CC_EXPECTED; 116 } 117} 118 | 47 EventNotifier io_notifier; 48 bool force_orb_pfch; 49 bool warned_orb_pfch; 50}; 51 52static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch, 53 const char *msg) 54{ --- 59 unchanged lines hidden (view full) --- 114 case -EFAULT: 115 default: 116 sch_gen_unit_exception(sch); 117 css_inject_io_interrupt(sch); 118 return IOINST_CC_EXPECTED; 119 } 120} 121 |
122static IOInstEnding vfio_ccw_handle_store(SubchDev *sch) 123{ 124 S390CCWDevice *cdev = sch->driver_data; 125 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 126 SCHIB *schib = &sch->curr_status; 127 struct ccw_schib_region *region = vcdev->schib_region; 128 SCHIB *s; 129 int ret; 130 131 /* schib region not available so nothing else to do */ 132 if (!region) { 133 return IOINST_CC_EXPECTED; 134 } 135 136 memset(region, 0, sizeof(*region)); 137 ret = pread(vcdev->vdev.fd, region, vcdev->schib_region_size, 138 vcdev->schib_region_offset); 139 140 if (ret == -1) { 141 /* 142 * Device is probably damaged, but store subchannel does not 143 * have a nonzero cc defined for this scenario. Log an error, 144 * and presume things are otherwise fine. 145 */ 146 error_report("vfio-ccw: store region read failed with errno=%d", errno); 147 return IOINST_CC_EXPECTED; 148 } 149 150 /* 151 * Selectively copy path-related bits of the SCHIB, 152 * rather than copying the entire struct. 153 */ 154 s = (SCHIB *)region->schib_area; 155 schib->pmcw.pnom = s->pmcw.pnom; 156 schib->pmcw.lpum = s->pmcw.lpum; 157 schib->pmcw.pam = s->pmcw.pam; 158 schib->pmcw.pom = s->pmcw.pom; 159 160 if (s->scsw.flags & SCSW_FLAGS_MASK_PNO) { 161 schib->scsw.flags |= SCSW_FLAGS_MASK_PNO; 162 } 163 164 return IOINST_CC_EXPECTED; 165} 166 |
|
119static int vfio_ccw_handle_clear(SubchDev *sch) 120{ 121 S390CCWDevice *cdev = sch->driver_data; 122 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 123 struct ccw_cmd_region *region = vcdev->async_cmd_region; 124 int ret; 125 126 if (!vcdev->async_cmd_region) { --- 250 unchanged lines hidden (view full) --- 377 if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) { 378 error_setg(errp, "vfio: Unexpected size of the async cmd region"); 379 goto out_err; 380 } 381 vcdev->async_cmd_region_offset = info->offset; 382 vcdev->async_cmd_region = g_malloc0(info->size); 383 } 384 | 167static int vfio_ccw_handle_clear(SubchDev *sch) 168{ 169 S390CCWDevice *cdev = sch->driver_data; 170 VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev); 171 struct ccw_cmd_region *region = vcdev->async_cmd_region; 172 int ret; 173 174 if (!vcdev->async_cmd_region) { --- 250 unchanged lines hidden (view full) --- 425 if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) { 426 error_setg(errp, "vfio: Unexpected size of the async cmd region"); 427 goto out_err; 428 } 429 vcdev->async_cmd_region_offset = info->offset; 430 vcdev->async_cmd_region = g_malloc0(info->size); 431 } 432 |
433 ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW, 434 VFIO_REGION_SUBTYPE_CCW_SCHIB, &info); 435 if (!ret) { 436 vcdev->schib_region_size = info->size; 437 if (sizeof(*vcdev->schib_region) != vcdev->schib_region_size) { 438 error_setg(errp, "vfio: Unexpected size of the schib region"); 439 goto out_err; 440 } 441 vcdev->schib_region_offset = info->offset; 442 vcdev->schib_region = g_malloc(info->size); 443 } 444 |
|
385 g_free(info); 386 return; 387 388out_err: | 445 g_free(info); 446 return; 447 448out_err: |
449 g_free(vcdev->schib_region); |
|
389 g_free(vcdev->async_cmd_region); 390 g_free(vcdev->io_region); 391 g_free(info); 392 return; 393} 394 395static void vfio_ccw_put_region(VFIOCCWDevice *vcdev) 396{ | 450 g_free(vcdev->async_cmd_region); 451 g_free(vcdev->io_region); 452 g_free(info); 453 return; 454} 455 456static void vfio_ccw_put_region(VFIOCCWDevice *vcdev) 457{ |
458 g_free(vcdev->schib_region); |
|
397 g_free(vcdev->async_cmd_region); 398 g_free(vcdev->io_region); 399} 400 401static void vfio_ccw_put_device(VFIOCCWDevice *vcdev) 402{ 403 g_free(vcdev->vdev.name); 404 vfio_put_base_device(&vcdev->vdev); --- 159 unchanged lines hidden (view full) --- 564 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 565 dc->realize = vfio_ccw_realize; 566 dc->unrealize = vfio_ccw_unrealize; 567 dc->reset = vfio_ccw_reset; 568 569 cdc->handle_request = vfio_ccw_handle_request; 570 cdc->handle_halt = vfio_ccw_handle_halt; 571 cdc->handle_clear = vfio_ccw_handle_clear; | 459 g_free(vcdev->async_cmd_region); 460 g_free(vcdev->io_region); 461} 462 463static void vfio_ccw_put_device(VFIOCCWDevice *vcdev) 464{ 465 g_free(vcdev->vdev.name); 466 vfio_put_base_device(&vcdev->vdev); --- 159 unchanged lines hidden (view full) --- 626 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 627 dc->realize = vfio_ccw_realize; 628 dc->unrealize = vfio_ccw_unrealize; 629 dc->reset = vfio_ccw_reset; 630 631 cdc->handle_request = vfio_ccw_handle_request; 632 cdc->handle_halt = vfio_ccw_handle_halt; 633 cdc->handle_clear = vfio_ccw_handle_clear; |
634 cdc->handle_store = vfio_ccw_handle_store; |
|
572} 573 574static const TypeInfo vfio_ccw_info = { 575 .name = TYPE_VFIO_CCW, 576 .parent = TYPE_S390_CCW, 577 .instance_size = sizeof(VFIOCCWDevice), 578 .class_init = vfio_ccw_class_init, 579}; 580 581static void register_vfio_ccw_type(void) 582{ 583 type_register_static(&vfio_ccw_info); 584} 585 586type_init(register_vfio_ccw_type) | 635} 636 637static const TypeInfo vfio_ccw_info = { 638 .name = TYPE_VFIO_CCW, 639 .parent = TYPE_S390_CCW, 640 .instance_size = sizeof(VFIOCCWDevice), 641 .class_init = vfio_ccw_class_init, 642}; 643 644static void register_vfio_ccw_type(void) 645{ 646 type_register_static(&vfio_ccw_info); 647} 648 649type_init(register_vfio_ccw_type) |