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

s390 vfio-ccw: Add bootindex property and IPLB data

Add bootindex property and iplb data for vfio-ccw devices. This allows us to
forward boot information into the bios for vfio-ccw devices.

Refactor s390_get_ccw_device() to return device type. This prevents us from
having to use messy casting logic in several places.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1554388475-18329-2-git-send-email-jjherne@linux.ibm.com>
[thuth: fixed "typedef struct VFIOCCWDevice" build failure with clang]
Signed-off-by: Thomas Huth <thuth@redhat.com>

authored by

Jason J. Herne and committed by
Thomas Huth
44445d86 532cc6da

+88 -18
+1
MAINTAINERS
··· 1445 1445 F: hw/vfio/ccw.c 1446 1446 F: hw/s390x/s390-ccw.c 1447 1447 F: include/hw/s390x/s390-ccw.h 1448 + F: include/hw/s390x/vfio-ccw.h 1448 1449 T: git https://github.com/cohuck/qemu.git s390-next 1449 1450 L: qemu-s390x@nongnu.org 1450 1451
+46 -15
hw/s390x/ipl.c
··· 19 19 #include "hw/loader.h" 20 20 #include "hw/boards.h" 21 21 #include "hw/s390x/virtio-ccw.h" 22 + #include "hw/s390x/vfio-ccw.h" 22 23 #include "hw/s390x/css.h" 23 24 #include "hw/s390x/ebcdic.h" 24 25 #include "ipl.h" ··· 303 304 ipl->qipl.boot_menu_timeout = cpu_to_be32(splash_time); 304 305 } 305 306 306 - static CcwDevice *s390_get_ccw_device(DeviceState *dev_st) 307 + #define CCW_DEVTYPE_NONE 0x00 308 + #define CCW_DEVTYPE_VIRTIO 0x01 309 + #define CCW_DEVTYPE_VIRTIO_NET 0x02 310 + #define CCW_DEVTYPE_SCSI 0x03 311 + #define CCW_DEVTYPE_VFIO 0x04 312 + 313 + static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype) 307 314 { 308 315 CcwDevice *ccw_dev = NULL; 316 + int tmp_dt = CCW_DEVTYPE_NONE; 309 317 310 318 if (dev_st) { 319 + VirtIONet *virtio_net_dev = (VirtIONet *) 320 + object_dynamic_cast(OBJECT(dev_st), TYPE_VIRTIO_NET); 311 321 VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *) 312 322 object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent), 313 323 TYPE_VIRTIO_CCW_DEVICE); 324 + VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *) 325 + object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW); 326 + 314 327 if (virtio_ccw_dev) { 315 328 ccw_dev = CCW_DEVICE(virtio_ccw_dev); 329 + if (virtio_net_dev) { 330 + tmp_dt = CCW_DEVTYPE_VIRTIO_NET; 331 + } else { 332 + tmp_dt = CCW_DEVTYPE_VIRTIO; 333 + } 334 + } else if (vfio_ccw_dev) { 335 + ccw_dev = CCW_DEVICE(vfio_ccw_dev); 336 + tmp_dt = CCW_DEVTYPE_VFIO; 316 337 } else { 317 338 SCSIDevice *sd = (SCSIDevice *) 318 339 object_dynamic_cast(OBJECT(dev_st), ··· 325 346 326 347 ccw_dev = (CcwDevice *)object_dynamic_cast(OBJECT(scsi_ccw), 327 348 TYPE_CCW_DEVICE); 349 + tmp_dt = CCW_DEVTYPE_SCSI; 328 350 } 329 351 } 352 + } 353 + if (devtype) { 354 + *devtype = tmp_dt; 330 355 } 331 356 return ccw_dev; 332 357 } ··· 335 360 { 336 361 DeviceState *dev_st; 337 362 CcwDevice *ccw_dev = NULL; 363 + SCSIDevice *sd; 364 + int devtype; 338 365 339 366 dev_st = get_boot_device(0); 340 367 if (dev_st) { 341 - ccw_dev = s390_get_ccw_device(dev_st); 368 + ccw_dev = s390_get_ccw_device(dev_st, &devtype); 342 369 } 343 370 344 371 /* 345 372 * Currently allow IPL only from CCW devices. 346 373 */ 347 374 if (ccw_dev) { 348 - SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st), 349 - TYPE_SCSI_DEVICE); 350 - 351 - if (sd) { 375 + switch (devtype) { 376 + case CCW_DEVTYPE_SCSI: 377 + sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st), 378 + TYPE_SCSI_DEVICE); 352 379 ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN); 353 380 ipl->iplb.blk0_len = 354 381 cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN); ··· 358 385 ipl->iplb.scsi.channel = cpu_to_be16(sd->channel); 359 386 ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno); 360 387 ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3; 361 - } else { 362 - VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st), 363 - TYPE_VIRTIO_NET); 364 - 388 + break; 389 + case CCW_DEVTYPE_VFIO: 390 + ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); 391 + ipl->iplb.pbt = S390_IPL_TYPE_CCW; 392 + ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno); 393 + ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; 394 + break; 395 + case CCW_DEVTYPE_VIRTIO_NET: 396 + ipl->netboot = true; 397 + /* Fall through to CCW_DEVTYPE_VIRTIO case */ 398 + case CCW_DEVTYPE_VIRTIO: 365 399 ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); 366 400 ipl->iplb.blk0_len = 367 401 cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN); 368 402 ipl->iplb.pbt = S390_IPL_TYPE_CCW; 369 403 ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno); 370 404 ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; 371 - 372 - if (vn) { 373 - ipl->netboot = true; 374 - } 405 + break; 375 406 } 376 407 377 408 if (!s390_ipl_set_loadparm(ipl->iplb.loadparm)) { ··· 530 561 !ipl->netboot && 531 562 ipl->iplb.pbt == S390_IPL_TYPE_CCW && 532 563 is_virtio_scsi_device(&ipl->iplb)) { 533 - CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0)); 564 + CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0), NULL); 534 565 535 566 if (ccw_dev && 536 567 cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno &&
+9
hw/s390x/s390-ccw.c
··· 124 124 g_free(cdev->mdevid); 125 125 } 126 126 127 + static void s390_ccw_instance_init(Object *obj) 128 + { 129 + S390CCWDevice *dev = S390_CCW_DEVICE(obj); 130 + 131 + device_add_bootindex_property(obj, &dev->bootindex, "bootindex", 132 + "/disk@0,0", DEVICE(obj), NULL); 133 + } 134 + 127 135 static void s390_ccw_class_init(ObjectClass *klass, void *data) 128 136 { 129 137 DeviceClass *dc = DEVICE_CLASS(klass); ··· 137 145 static const TypeInfo s390_ccw_info = { 138 146 .name = TYPE_S390_CCW, 139 147 .parent = TYPE_CCW_DEVICE, 148 + .instance_init = s390_ccw_instance_init, 140 149 .instance_size = sizeof(S390CCWDevice), 141 150 .class_size = sizeof(S390CCWDeviceClass), 142 151 .class_init = s390_ccw_class_init,
+3 -3
hw/vfio/ccw.c
··· 21 21 #include "hw/vfio/vfio.h" 22 22 #include "hw/vfio/vfio-common.h" 23 23 #include "hw/s390x/s390-ccw.h" 24 + #include "hw/s390x/vfio-ccw.h" 24 25 #include "hw/s390x/ccw-device.h" 25 26 #include "exec/address-spaces.h" 26 27 #include "qemu/error-report.h" 27 28 28 - #define TYPE_VFIO_CCW "vfio-ccw" 29 - typedef struct VFIOCCWDevice { 29 + struct VFIOCCWDevice { 30 30 S390CCWDevice cdev; 31 31 VFIODevice vdev; 32 32 uint64_t io_region_size; ··· 35 35 EventNotifier io_notifier; 36 36 bool force_orb_pfch; 37 37 bool warned_orb_pfch; 38 - } VFIOCCWDevice; 38 + }; 39 39 40 40 static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch, 41 41 const char *msg)
+1
include/hw/s390x/s390-ccw.h
··· 27 27 CcwDevice parent_obj; 28 28 CssDevId hostid; 29 29 char *mdevid; 30 + int32_t bootindex; 30 31 } S390CCWDevice; 31 32 32 33 typedef struct S390CCWDeviceClass {
+28
include/hw/s390x/vfio-ccw.h
··· 1 + /* 2 + * vfio based subchannel assignment support 3 + * 4 + * Copyright 2017, 2019 IBM Corp. 5 + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 6 + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 7 + * Pierre Morel <pmorel@linux.vnet.ibm.com> 8 + * 9 + * This work is licensed under the terms of the GNU GPL, version 2 or (at 10 + * your option) any later version. See the COPYING file in the top-level 11 + * directory. 12 + */ 13 + 14 + #ifndef HW_VFIO_CCW_H 15 + #define HW_VFIO_CCW_H 16 + 17 + #include "hw/vfio/vfio-common.h" 18 + #include "hw/s390x/s390-ccw.h" 19 + #include "hw/s390x/ccw-device.h" 20 + 21 + #define TYPE_VFIO_CCW "vfio-ccw" 22 + #define VFIO_CCW(obj) \ 23 + OBJECT_CHECK(VFIOCCWDevice, (obj), TYPE_VFIO_CCW) 24 + 25 + #define TYPE_VFIO_CCW "vfio-ccw" 26 + typedef struct VFIOCCWDevice VFIOCCWDevice; 27 + 28 + #endif