]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
S390: Add support for virtio-s390 devices.
authorViktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Fri, 29 Jun 2012 15:02:05 +0000 (17:02 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 11 Jul 2012 09:19:05 +0000 (11:19 +0200)
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@linux.vnet.ibm.com>
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_command.c

index 3fb90db47b50c000c59be35e25af99592a69ac79..4f8c57a0b358c39e9d6172ae5089952b357f4128 100644 (file)
@@ -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"));
@@ -4674,6 +4677,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"));
@@ -9076,7 +9080,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 ||
index 7d5d60bd269aa58d45df82fa2d1b6050a2d5c747..5e5374af52fceec960b572d65f4e0319bf1b1b56 100644 (file)
@@ -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
 };
index 1e12a3995c53fe1e4997e2e1d9918c350407ec62..9e4d927dd5e0ba9d004f5f445decc0e6d2b5695c 100644 (file)
@@ -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,10 @@ 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\"") ||
+        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 */
     if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) &&
index 83c135b7fe8fde7d4790bf2fd14a6de288b8cae9..9b5ff302b7edc44b20db59772b32acf9139aa4d4 100644 (file)
@@ -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 */
 };
index 428050f1e211131b014989cb5b44b6749e14d60d..ae48678083fdc9a7a01841fa526d6c9e3252d39c 100644 (file)
@@ -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,
@@ -1000,6 +1061,10 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
     if (rc)
         return rc;
 
+    rc = qemuDomainAssignS390Addresses(def, qemuCaps);
+    if (rc)
+        return rc;
+
     return qemuDomainAssignPCIAddresses(def, qemuCaps, obj);
 }
 
@@ -1544,7 +1609,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) {
@@ -2021,7 +2089,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;
 
@@ -2451,7 +2525,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)) {
@@ -2709,6 +2788,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");
         }
@@ -2804,7 +2886,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;
@@ -3607,7 +3694,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)