[libvirt] [PATCHv3 3/5] S390: Add support for virtio-s390 devices.

Michal Privoznik mprivozn at redhat.com
Tue Jul 3 16:18:26 UTC 2012


On 29.06.2012 17:02, Viktor Mihajlovski wrote:
> 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 at linux.vnet.ibm.com>
> ---
>  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);

I think this could be joined into one if with ||

>  
>      /* 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)
> 


ACK with this squashed in:

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b6e5bd1..9e4d927 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1431,11 +1431,9 @@ 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\""))
+    if (strstr(str, "name \"virtio-blk-s390\"") ||
+        strstr(str, "name \"virtio-net-s390\"") ||
+        strstr(str, "name \"virtio-serial-s390\""))
         qemuCapsSet(flags, QEMU_CAPS_VIRTIO_S390);

     /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */


Michal




More information about the libvir-list mailing list