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.
Signed-off-by: Viktor Mihajlovski <mihajlov(a)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 81c6308..4db771e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -150,7 +150,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,
@@ -2130,7 +2131,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 */
@@ -4121,6 +4123,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"));
@@ -4646,6 +4649,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"));
@@ -9048,7 +9052,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 44280ba..0b54646 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 0c01cb0..9e8bded 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -165,6 +165,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"hda-micro", /* 95 */
"dump-guest-memory",
+ "virtio-s390",
);
@@ -1427,6 +1428,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 640f7f5..c117a39 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -132,6 +132,7 @@ enum qemuCapsFlags {
QEMU_CAPS_NO_USER_CONFIG = 94, /* -no-user-config */
QEMU_CAPS_HDA_MICRO = 95, /* -device hda-micro */
QEMU_CAPS_DUMP_GUEST_MEMORY = 96, /* dump-guest-memory command */
+ QEMU_CAPS_VIRTIO_S390 = 97, /* -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 bee48e1..8b14d10 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -734,6 +734,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)) {
@@ -2706,6 +2785,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");
}
@@ -2801,7 +2883,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;
@@ -3604,7 +3691,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
--
Mit freundlichen Grüßen/Kind Regards
Viktor Mihajlovski
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294