qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

vfio-ccw: Add support for the schib region

The schib region can be used to obtain the latest SCHIB from the host
passthrough subchannel. Since the guest SCHIB is virtualized,
we currently only update the path related information so that the
guest is aware of any path related changes when it issues the
'stsch' instruction.

Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20200505125757.98209-4-farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

authored by

Farhan Ali and committed by
Cornelia Huck
46ea3841 2a3b9cba

+99 -5
+11 -2
hw/s390x/css.c
··· 1335 1335 } 1336 1336 } 1337 1337 1338 - int css_do_stsch(SubchDev *sch, SCHIB *schib) 1338 + IOInstEnding css_do_stsch(SubchDev *sch, SCHIB *schib) 1339 1339 { 1340 + int ret; 1341 + 1342 + /* 1343 + * For some subchannels, we may want to update parts of 1344 + * the schib (e.g., update path masks from the host device 1345 + * for passthrough subchannels). 1346 + */ 1347 + ret = s390_ccw_store(sch); 1348 + 1340 1349 /* Use current status. */ 1341 1350 copy_schib_to_guest(schib, &sch->curr_status); 1342 - return 0; 1351 + return ret; 1343 1352 } 1344 1353 1345 1354 static void copy_pmcw_from_guest(PMCW *dest, const PMCW *src)
+21
hw/s390x/s390-ccw.c
··· 51 51 return cdc->handle_clear(sch); 52 52 } 53 53 54 + IOInstEnding s390_ccw_store(SubchDev *sch) 55 + { 56 + S390CCWDeviceClass *cdc = NULL; 57 + int ret = IOINST_CC_EXPECTED; 58 + 59 + /* 60 + * This code is called for both virtual and passthrough devices, 61 + * but only applies to to the latter. This ugly check makes that 62 + * distinction for us. 63 + */ 64 + if (object_dynamic_cast(OBJECT(sch->driver_data), TYPE_S390_CCW)) { 65 + cdc = S390_CCW_DEVICE_GET_CLASS(sch->driver_data); 66 + } 67 + 68 + if (cdc && cdc->handle_store) { 69 + ret = cdc->handle_store(sch); 70 + } 71 + 72 + return ret; 73 + } 74 + 54 75 static void s390_ccw_get_dev_info(S390CCWDevice *cdev, 55 76 char *sysfsdev, 56 77 Error **errp)
+63
hw/vfio/ccw.c
··· 41 41 uint64_t async_cmd_region_size; 42 42 uint64_t async_cmd_region_offset; 43 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 47 EventNotifier io_notifier; 45 48 bool force_orb_pfch; 46 49 bool warned_orb_pfch; ··· 116 119 } 117 120 } 118 121 122 + static 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 + 119 167 static int vfio_ccw_handle_clear(SubchDev *sch) 120 168 { 121 169 S390CCWDevice *cdev = sch->driver_data; ··· 382 430 vcdev->async_cmd_region = g_malloc0(info->size); 383 431 } 384 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 445 g_free(info); 386 446 return; 387 447 388 448 out_err: 449 + g_free(vcdev->schib_region); 389 450 g_free(vcdev->async_cmd_region); 390 451 g_free(vcdev->io_region); 391 452 g_free(info); ··· 394 455 395 456 static void vfio_ccw_put_region(VFIOCCWDevice *vcdev) 396 457 { 458 + g_free(vcdev->schib_region); 397 459 g_free(vcdev->async_cmd_region); 398 460 g_free(vcdev->io_region); 399 461 } ··· 569 631 cdc->handle_request = vfio_ccw_handle_request; 570 632 cdc->handle_halt = vfio_ccw_handle_halt; 571 633 cdc->handle_clear = vfio_ccw_handle_clear; 634 + cdc->handle_store = vfio_ccw_handle_store; 572 635 } 573 636 574 637 static const TypeInfo vfio_ccw_info = {
+2 -1
include/hw/s390x/css.h
··· 218 218 219 219 int s390_ccw_halt(SubchDev *sch); 220 220 int s390_ccw_clear(SubchDev *sch); 221 + IOInstEnding s390_ccw_store(SubchDev *sch); 221 222 222 223 typedef enum { 223 224 CSS_IO_ADAPTER_VIRTIO = 0, ··· 242 243 uint16_t schid); 243 244 bool css_subch_visible(SubchDev *sch); 244 245 void css_conditional_io_interrupt(SubchDev *sch); 245 - int css_do_stsch(SubchDev *sch, SCHIB *schib); 246 + IOInstEnding css_do_stsch(SubchDev *sch, SCHIB *schib); 246 247 bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid); 247 248 IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *schib); 248 249 IOInstEnding css_do_xsch(SubchDev *sch);
+1
include/hw/s390x/s390-ccw.h
··· 37 37 IOInstEnding (*handle_request) (SubchDev *sch); 38 38 int (*handle_halt) (SubchDev *sch); 39 39 int (*handle_clear) (SubchDev *sch); 40 + IOInstEnding (*handle_store) (SubchDev *sch); 40 41 } S390CCWDeviceClass; 41 42 42 43 #endif
+1 -2
target/s390x/ioinst.c
··· 292 292 sch = css_find_subch(m, cssid, ssid, schid); 293 293 if (sch) { 294 294 if (css_subch_visible(sch)) { 295 - css_do_stsch(sch, &schib); 296 - cc = 0; 295 + cc = css_do_stsch(sch, &schib); 297 296 } else { 298 297 /* Indicate no more subchannels in this css/ss */ 299 298 cc = 3;