diff --git a/libvirt.orig/src/nodeinfo.c b/libvirt/src/nodeinfo.c index 22d53e5..126bf7a 100644 --- a/libvirt.orig/src/nodeinfo.c +++ b/libvirt/src/nodeinfo.c @@ -164,7 +164,11 @@ cleanup: static int parse_socket(unsigned int cpu) { +# if defined __s390x__ || defined __s390__ + return 0; /* s390 does not implement physical_package_id by now */ +# else return get_cpu_value(cpu, "topology/physical_package_id", false); +# endif } int linuxNodeInfoCPUPopulate(FILE *cpuinfo, @@ -195,6 +199,50 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, * has no knowledge of NUMA nodes */ /* NOTE: hyperthreads are ignored here; they are parsed out of /sys */ +# if defined __s390x__ || defined __s390__ +/* cat /proc/cpuinfo under s390x: +vendor_id : IBM/S390 +# processors : 2 +bogomips per cpu: 5681.00 +features : esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs +processor 0: version = 00, identification = 08A750, machine = 2096 +processor 1: version = 00, identification = 08A750, machine = 2096 +*/ + while (fgets(line, sizeof(line), cpuinfo) != NULL) { + char *buf = line; + if (STRPREFIX(buf, "# processors")) { /* Number of processors */ + char *p; + unsigned int id; + buf += 12; + while (*buf && c_isspace(*buf)) + buf++; + if (*buf != ':' || !buf[1]) { + nodeReportError(VIR_ERR_INTERNAL_ERROR, + "parsing cpuinfo cpu count %c", *buf); + return -1; + } + if (virStrToLong_ui(buf+1, &p, 10, &id) == 0 + && (*p == '\0' || c_isspace(*p)) + && id > nodeinfo->cores) { + nodeinfo->cpus = id; + //nodeinfo->cores = 1; // is already set. + nodeinfo->mhz = 1400; /* z9 BC */ + } + } + } + +// I searched for parsing the CPU MHz value, but I am not sure if this is the correct path: +// cat /sys/devices/system/cpu/cpu0/capabilities => 1760 + +/* lscpu shows following: +Architecture: s390x +CPU(s): 2 +Thread(s) per core: 1 +Core(s) per socket: 64 +CPU socket(s): 0 +Vendor ID: IBM/S390* +*/ +# else /* no s390 */ while (fgets(line, sizeof(line), cpuinfo) != NULL) { char *buf = line; if (STRPREFIX(buf, "processor")) { /* aka a single logical CPU */ @@ -239,6 +287,7 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, nodeinfo->cores = id; } } +# endif /* s390 */ if (!nodeinfo->cpus) { nodeReportError(VIR_ERR_INTERNAL_ERROR, diff --git a/libvirt.orig/src/qemu/qemu_command.c b/libvirt/src/qemu/qemu_command.c index a0f86a3..a49069f 100644 --- a/libvirt.orig/src/qemu/qemu_command.c +++ b/libvirt/src/qemu/qemu_command.c @@ -857,7 +857,12 @@ int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs, return -1; } +// well this is not the best way, but overwriting all 'dev->type' with 'pci' is also not a good solution ... +# if ! ( defined __s390x__ || defined __s390__ ) dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; +# else + dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390; +# endif dev->addr.pci = maybe.addr.pci; addrs->nextslot = i + 1; @@ -1090,7 +1095,8 @@ static int qemuBuildDeviceAddressStr(virBufferPtr buf, virDomainDeviceInfoPtr info) { - if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + switch(info->type){ + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: if (info->addr.pci.domain != 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only PCI device addresses with domain=0 are supported")); @@ -1114,6 +1120,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, * to pciNN.0 where NN is the domain number */ virBufferVSprintf(buf, ",bus=pci.0,addr=0x%x", info->addr.pci.slot); + break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390: + // if you try to add 'addr=' to an Device, qemu-system-s390x prints: "Property '*.addr' not found" + + // there is also no way to make an difference with a dot and a number for more than one bus ... + // if you try to do so, qemu will crash with following: "Bus 's390-virtio.0' not found" + virBufferVSprintf(buf, ",bus=s390-virtio"); } return 0; } @@ -1382,7 +1395,11 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk, disk->info.addr.drive.unit); break; case VIR_DOMAIN_DISK_BUS_VIRTIO: +# if ( defined __s390x__ || defined __s390__ ) + virBufferAddLit(&opt, "virtio-blk-s390"); +# else virBufferAddLit(&opt, "virtio-blk-pci"); +# endif qemuBuildDeviceAddressStr(&opt, &disk->info); break; case VIR_DOMAIN_DISK_BUS_USB: @@ -1488,9 +1505,17 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def) break; case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: - if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + + switch(def->info.type){ + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: virBufferAddLit(&buf, "virtio-serial-pci"); - } else { + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390: + virBufferAddLit(&buf, "virtio-serial-s390"); + break; + + default: virBufferAddLit(&buf, "virtio-serial"); } virBufferVSprintf(&buf, ",id=" QEMU_VIRTIO_SERIAL_PREFIX "%d", @@ -1566,7 +1591,11 @@ qemuBuildNicDevStr(virDomainNetDefPtr net, if (!net->model) { nic = "rtl8139"; } else if (STREQ(net->model, "virtio")) { +# if defined __s390x__ || defined __s390__ + nic = "virtio-net-s390"; +# else nic = "virtio-net-pci"; +# endif } else { nic = net->model; } @@ -2952,8 +2981,10 @@ qemuBuildCommandLine(virConnectPtr conn, def->onReboot != VIR_DOMAIN_LIFECYCLE_RESTART) virCommandAddArg(cmd, "-no-reboot"); +# if ! ( defined __s390x__ || defined __s390__ ) if (!(def->features & (1 << VIR_DOMAIN_FEATURE_ACPI))) virCommandAddArg(cmd, "-no-acpi"); +# endif if (!def->os.bootloader) { for (i = 0 ; i < def->os.nBootDevs ; i++) { diff --git a/libvirt.orig/src/conf/domain_conf.c b/libvirt/src/conf/domain_conf.c index b1cc6c8..a2675a6 100644 --- a/libvirt.orig/src/conf/domain_conf.c +++ b/libvirt/src/conf/domain_conf.c @@ -108,6 +108,7 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "none", "pci", + "s390-virtio", "drive", "virtio-serial") @@ -1109,6 +1110,9 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: return virDomainDevicePCIAddressIsValid(&info->addr.pci); + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390: + return 1; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: return virDomainDeviceDriveAddressIsValid(&info->addr.drive); } @@ -1271,6 +1275,9 @@ static int virDomainDeviceInfoFormat(virBufferPtr buf, info->addr.pci.function); break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390: + break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: virBufferVSprintf(buf, " controller='%d' bus='%d' unit='%d'", info->addr.drive.controller, @@ -1515,6 +1522,9 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, goto cleanup; break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390: + break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: if (virDomainDeviceDriveAddressParseXML(address, &info->addr.drive) < 0) goto cleanup; @@ -1948,7 +1958,12 @@ virDomainDiskDefParseXML(virCapsPtr caps, devaddr); goto error; } +// well this is not the best way, but overwriting all 'dev->info.type' with 'pci' is also not a good solution ... +# if ( defined __s390x__ || defined __s390__ ) + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390; +# else def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; +# endif } else { if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) goto error; @@ -2106,9 +2121,10 @@ virDomainControllerDefParseXML(xmlNodePtr node, } if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && - def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Controllers must use the 'pci' address type")); + _("Controllers must use the 'pci' or 's390-virtio' address type")); goto error; } @@ -2512,7 +2528,12 @@ virDomainNetDefParseXML(virCapsPtr caps, devaddr); goto error; } +// well this is not the best way, but overwriting all 'dev->info.type' with 'pci' is also not a good solution ... +# if ( defined __s390x__ || defined __s390__ ) + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390; +# else def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; +# endif } else { if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) goto error; @@ -2521,7 +2542,8 @@ virDomainNetDefParseXML(virCapsPtr caps, /* XXX what about ISA/USB based NIC models - once we support * 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_PCI) { + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Network interfaces must use 'pci' address type")); goto error; @@ -4228,7 +4250,12 @@ virDomainHostdevSubsysPciDefParseXML(const xmlNodePtr node, VIR_FREE(devaddr); goto out; } +// well this is not the best way, but overwriting all 'dev->info.type' with 'pci' is also not a good solution ... +# if ( defined __s390x__ || defined __s390__ ) + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390; +# else def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; +# endif } else { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("unknown pci source type '%s'"), @@ -4325,9 +4352,10 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, switch (def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && - def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("PCI host devices must use 'pci' address type")); + _("PCI host devices must use 'pci' or 's390-virtio' address type")); goto error; } break; diff --git a/libvirt.orig/src/conf/domain_conf.h b/libvirt/src/conf/domain_conf.h index 871fa9a..5db6c55 100644 --- a/libvirt.orig/src/conf/domain_conf.h +++ b/libvirt/src/conf/domain_conf.h @@ -71,6 +71,7 @@ enum virDomainVirtType { enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_S390, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL,