The s390(x) architecture doesn't feature a PCI bus. For the purpose of supporting virtio devices a virtual bus called virtio-s390 is used. A new address type VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 is used to distinguish the virtio devices on s390 from PCI-based virtio devices. V3 Change: updated QEMU_CAPS_VIRTIO_S390 to fit upstream. Signed-off-by: Viktor Mihajlovski <mihajlov@xxxxxxxxxxxxxxxxxx> --- src/conf/domain_conf.c | 11 +++- src/conf/domain_conf.h | 1 + src/qemu/qemu_capabilities.c | 7 +++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 98 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 110 insertions(+), 8 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 4086dac..cf7c757 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -149,7 +149,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "virtio-serial", "ccid", "usb", - "spapr-vio") + "spapr-vio", + "virtio-s390") VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti, VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST, @@ -2132,7 +2133,8 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virBufferAddLit(buf, "/>\n"); } - if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE || + info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) return 0; /* We'll be in domain/devices/[device type]/ so 3 level indent */ @@ -4123,6 +4125,7 @@ virDomainControllerDefParseXML(xmlNodePtr node, if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Controllers must use the 'pci' address type")); @@ -4676,6 +4679,7 @@ virDomainNetDefParseXML(virCapsPtr caps, * them we should make sure address type is correct */ if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Network interfaces must use 'pci' address type")); @@ -9078,7 +9082,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, def->memballoon = memballoon; VIR_FREE(nodes); - } else { + } else if (!STREQ(def->os.arch,"s390x")) { + /* TODO: currently no balloon support on s390 -> no default balloon */ if (def->virtType == VIR_DOMAIN_VIRT_XEN || def->virtType == VIR_DOMAIN_VIRT_QEMU || def->virtType == VIR_DOMAIN_VIRT_KQEMU || diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7d5d60b..5e5374a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -172,6 +172,7 @@ enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST }; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 1e12a39..b6e5bd1 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -166,6 +166,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, "hda-micro", /* 95 */ "dump-guest-memory", "nec-usb-xhci", + "virtio-s390", ); @@ -1430,6 +1431,12 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags) qemuCapsSet(flags, QEMU_CAPS_USB_HUB); if (strstr(str, "name \"ich9-ahci\"")) qemuCapsSet(flags, QEMU_CAPS_ICH9_AHCI); + if (strstr(str, "name \"virtio-blk-s390\"")) + qemuCapsSet(flags, QEMU_CAPS_VIRTIO_S390); + if (strstr(str, "name \"virtio-net-s390\"")) + qemuCapsSet(flags, QEMU_CAPS_VIRTIO_S390); + if (strstr(str, "name \"virtio-serial-s390\"")) + qemuCapsSet(flags, QEMU_CAPS_VIRTIO_S390); /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */ if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) && diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 83c135b..9b5ff30 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -133,6 +133,7 @@ enum qemuCapsFlags { QEMU_CAPS_HDA_MICRO = 95, /* -device hda-micro */ QEMU_CAPS_DUMP_GUEST_MEMORY = 96, /* dump-guest-memory command */ QEMU_CAPS_NEC_USB_XHCI = 97, /* -device nec-usb-xhci */ + QEMU_CAPS_VIRTIO_S390 = 98, /* -device virtio-*-s390 */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5edf915..99dbc1a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -735,6 +735,67 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps) return -1; } +static void +qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def, + enum virDomainDeviceAddressType type) +{ + /* + declare address-less virtio devices to be of address type 'type' + only disks, networks, consoles and controllers for now + */ + int i; + + for (i = 0; i < def->ndisks ; i++) { + if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_VIRTIO && + def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + def->disks[i]->info.type = type; + } + + for (i = 0; i < def->nnets ; i++) { + if (STREQ(def->nets[i]->model,"virtio") && + def->nets[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + def->nets[i]->info.type = type; + } + + for (i = 0; i < def->ncontrollers ; i++) { + if (def->controllers[i]->type == + VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL && + def->controllers[i]->info.type == + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + def->controllers[i]->info.type = type; + } + +} + +static int +qemuDomainAssignS390Addresses(virDomainDefPtr def, virBitmapPtr qemuCaps) +{ + int ret = -1; + virBitmapPtr localCaps = NULL; + + if (!qemuCaps) { + /* need to get information from real environment */ + if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch, + NULL, + &localCaps) < 0) + goto cleanup; + qemuCaps = localCaps; + } + + if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) { + /* deal with legacy virtio-s390 */ + qemuDomainPrimeS390VirtioDevices( + def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390); + } + + ret = 0; + +cleanup: + qemuCapsFree(localCaps); + + return ret; +} + static int qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED, virDomainDeviceDefPtr device ATTRIBUTE_UNUSED, @@ -1001,6 +1062,10 @@ int qemuDomainAssignAddresses(virDomainDefPtr def, virBitmapPtr qemuCaps, if (rc) return rc; + rc = qemuDomainAssignS390Addresses(def, qemuCaps); + if (rc) + return rc; + return qemuDomainAssignPCIAddresses(def, qemuCaps, obj); } @@ -1545,7 +1610,10 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) continue; - if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) + /* don't touch s390 devices */ + if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI || + def->disks[i]->info.type == + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) continue; if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { @@ -2020,7 +2088,13 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, break; case VIR_DOMAIN_DISK_BUS_VIRTIO: - /* Each virtio drive is a separate PCI device, no unit/busid or index */ + if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && + (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)) { + /* Paranoia - leave in here for now */ + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected address type for s390-virtio disk")); + goto error; + } idx = -1; break; @@ -2450,7 +2524,12 @@ qemuBuildDriveDevStr(virDomainDefPtr def, disk->info.addr.drive.unit); break; case VIR_DOMAIN_DISK_BUS_VIRTIO: - virBufferAddLit(&opt, "virtio-blk-pci"); + if (disk->info.type == + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) { + virBufferAddLit(&opt, "virtio-blk-s390"); + } else { + virBufferAddLit(&opt, "virtio-blk-pci"); + } qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps); if (disk->event_idx && qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) { @@ -2708,6 +2787,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { virBufferAddLit(&buf, "virtio-serial-pci"); + } else if (def->info.type == + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) { + virBufferAddLit(&buf, "virtio-serial-s390"); } else { virBufferAddLit(&buf, "virtio-serial"); } @@ -2803,7 +2885,12 @@ qemuBuildNicDevStr(virDomainNetDefPtr net, if (!net->model) { nic = "rtl8139"; } else if (STREQ(net->model, "virtio")) { - nic = "virtio-net-pci"; + if (net->info.type == + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) { + nic = "virtio-net-s390"; + } else { + nic = "virtio-net-pci"; + } usingVirtio = true; } else { nic = net->model; @@ -3606,7 +3693,8 @@ qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev, return NULL; } - if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) { /* Check it's a virtio-serial address */ if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL) -- 1.7.0.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list