S390: Add support for virtio-s390 devices.
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>
This commit is contained in:
parent
6e15887f30
commit
d0304eaac7
@ -149,7 +149,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
|
|||||||
"virtio-serial",
|
"virtio-serial",
|
||||||
"ccid",
|
"ccid",
|
||||||
"usb",
|
"usb",
|
||||||
"spapr-vio")
|
"spapr-vio",
|
||||||
|
"virtio-s390")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti,
|
VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti,
|
||||||
VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST,
|
VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST,
|
||||||
@ -2132,7 +2133,8 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
|
|||||||
virBufferAddLit(buf, "/>\n");
|
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;
|
return 0;
|
||||||
|
|
||||||
/* We'll be in domain/devices/[device type]/ so 3 level indent */
|
/* 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 &&
|
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_SPAPRVIO &&
|
||||||
|
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 &&
|
||||||
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Controllers must use the 'pci' address type"));
|
_("Controllers must use the 'pci' address type"));
|
||||||
@ -4674,6 +4677,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
* them we should make sure address type is correct */
|
* them we should make sure address type is correct */
|
||||||
if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
|
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_SPAPRVIO &&
|
||||||
|
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 &&
|
||||||
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Network interfaces must use 'pci' address type"));
|
_("Network interfaces must use 'pci' address type"));
|
||||||
@ -9076,7 +9080,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
|||||||
|
|
||||||
def->memballoon = memballoon;
|
def->memballoon = memballoon;
|
||||||
VIR_FREE(nodes);
|
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 ||
|
if (def->virtType == VIR_DOMAIN_VIRT_XEN ||
|
||||||
def->virtType == VIR_DOMAIN_VIRT_QEMU ||
|
def->virtType == VIR_DOMAIN_VIRT_QEMU ||
|
||||||
def->virtType == VIR_DOMAIN_VIRT_KQEMU ||
|
def->virtType == VIR_DOMAIN_VIRT_KQEMU ||
|
||||||
|
@ -172,6 +172,7 @@ enum virDomainDeviceAddressType {
|
|||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID,
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID,
|
||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB,
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB,
|
||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO,
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO,
|
||||||
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390,
|
||||||
|
|
||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
|
||||||
};
|
};
|
||||||
|
@ -166,6 +166,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
|
|||||||
"hda-micro", /* 95 */
|
"hda-micro", /* 95 */
|
||||||
"dump-guest-memory",
|
"dump-guest-memory",
|
||||||
"nec-usb-xhci",
|
"nec-usb-xhci",
|
||||||
|
"virtio-s390",
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1430,6 +1431,10 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
|
|||||||
qemuCapsSet(flags, QEMU_CAPS_USB_HUB);
|
qemuCapsSet(flags, QEMU_CAPS_USB_HUB);
|
||||||
if (strstr(str, "name \"ich9-ahci\""))
|
if (strstr(str, "name \"ich9-ahci\""))
|
||||||
qemuCapsSet(flags, QEMU_CAPS_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 */
|
/* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
|
||||||
if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) &&
|
if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) &&
|
||||||
|
@ -133,6 +133,7 @@ enum qemuCapsFlags {
|
|||||||
QEMU_CAPS_HDA_MICRO = 95, /* -device hda-micro */
|
QEMU_CAPS_HDA_MICRO = 95, /* -device hda-micro */
|
||||||
QEMU_CAPS_DUMP_GUEST_MEMORY = 96, /* dump-guest-memory command */
|
QEMU_CAPS_DUMP_GUEST_MEMORY = 96, /* dump-guest-memory command */
|
||||||
QEMU_CAPS_NEC_USB_XHCI = 97, /* -device nec-usb-xhci */
|
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 */
|
QEMU_CAPS_LAST, /* this must always be the last item */
|
||||||
};
|
};
|
||||||
|
@ -735,6 +735,67 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps)
|
|||||||
return -1;
|
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
|
static int
|
||||||
qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
||||||
virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
|
virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
|
||||||
@ -1000,6 +1061,10 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
rc = qemuDomainAssignS390Addresses(def, qemuCaps);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return qemuDomainAssignPCIAddresses(def, qemuCaps, obj);
|
return qemuDomainAssignPCIAddresses(def, qemuCaps, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1544,7 +1609,10 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
|
|||||||
if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
|
if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
|
||||||
continue;
|
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;
|
continue;
|
||||||
|
|
||||||
if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
|
if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
|
||||||
@ -2021,7 +2089,13 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DISK_BUS_VIRTIO:
|
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;
|
idx = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2451,7 +2525,12 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
|
|||||||
disk->info.addr.drive.unit);
|
disk->info.addr.drive.unit);
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DISK_BUS_VIRTIO:
|
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);
|
qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
|
||||||
if (disk->event_idx &&
|
if (disk->event_idx &&
|
||||||
qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) {
|
qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) {
|
||||||
@ -2709,6 +2788,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
|
|||||||
case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
|
case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
|
||||||
if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
||||||
virBufferAddLit(&buf, "virtio-serial-pci");
|
virBufferAddLit(&buf, "virtio-serial-pci");
|
||||||
|
} else if (def->info.type ==
|
||||||
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
|
||||||
|
virBufferAddLit(&buf, "virtio-serial-s390");
|
||||||
} else {
|
} else {
|
||||||
virBufferAddLit(&buf, "virtio-serial");
|
virBufferAddLit(&buf, "virtio-serial");
|
||||||
}
|
}
|
||||||
@ -2804,7 +2886,12 @@ qemuBuildNicDevStr(virDomainNetDefPtr net,
|
|||||||
if (!net->model) {
|
if (!net->model) {
|
||||||
nic = "rtl8139";
|
nic = "rtl8139";
|
||||||
} else if (STREQ(net->model, "virtio")) {
|
} 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;
|
usingVirtio = true;
|
||||||
} else {
|
} else {
|
||||||
nic = net->model;
|
nic = net->model;
|
||||||
@ -3607,7 +3694,8 @@ qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev,
|
|||||||
return NULL;
|
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 */
|
/* Check it's a virtio-serial address */
|
||||||
if (dev->info.type !=
|
if (dev->info.type !=
|
||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL)
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user