From: Michael Ellerman <michaele(a)au1.ibm.com>
For QEMU PPC64 we have a machine type ("pseries") which has a virtual
bus called "spapr-vio". We need to be able to create devices on this
bus, and as such need a way to specify the address for those devices.
This patch adds a new address type "spapr-vio", which achieves this.
The addressing is specified with a "reg" property in the address
definition. The reg is optional, if it is not specified QEMU will
auto-assign an address for the device.
Signed-off-by: Michael Ellerman <michael(a)ellerman.id.au>
---
src/conf/domain_conf.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 9 +++++++++
src/qemu/qemu_command.c | 5 +++++
3 files changed, 56 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5de33b9..665a0cd 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -139,7 +139,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"drive",
"virtio-serial",
"ccid",
- "usb")
+ "usb",
+ "spapr-vio")
VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti,
VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST,
@@ -1909,6 +1910,11 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
info->addr.usb.port);
break;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO:
+ if (info->addr.spaprvio.has_reg)
+ virBufferAsprintf(buf, " reg='%#llx'",
info->addr.spaprvio.reg);
+ break;
+
default:
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown address type '%d'"),
info->type);
@@ -2168,6 +2174,34 @@ cleanup:
}
static int
+virDomainDeviceSpaprVioAddressParseXML(xmlNodePtr node,
+ virDomainDeviceSpaprVioAddressPtr addr)
+{
+ char *reg;
+ int ret;
+
+ memset(addr, 0, sizeof(*addr));
+ addr->has_reg = false;
+
+ reg = virXMLPropString(node, "reg");
+ if (reg) {
+ if (virStrToLong_ull(reg, NULL, 16, &addr->reg) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse <address> 'reg'
attribute"));
+ ret = -1;
+ goto cleanup;
+ }
+
+ addr->has_reg = true;
+ }
+
+ ret = 0;
+cleanup:
+ VIR_FREE(reg);
+ return ret;
+}
+
+static int
virDomainDeviceUSBMasterParseXML(xmlNodePtr node,
virDomainDeviceUSBMasterPtr master)
{
@@ -2280,6 +2314,11 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
goto cleanup;
break;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO:
+ if (virDomainDeviceSpaprVioAddressParseXML(address, &info->addr.spaprvio)
< 0)
+ goto cleanup;
+ break;
+
default:
/* Should not happen */
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -3174,6 +3213,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_PCI) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Controllers must use the 'pci' address
type"));
@@ -3563,6 +3603,7 @@ 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_SPAPRVIO &&
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Network interfaces must use 'pci' address
type"));
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d6ed898..0ed6aba 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -69,6 +69,7 @@ enum virDomainDeviceAddressType {
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB,
+ VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
};
@@ -121,6 +122,13 @@ struct _virDomainDeviceUSBAddress {
char *port;
};
+typedef struct _virDomainDeviceSpaprVioAddress virDomainDeviceSpaprVioAddress;
+typedef virDomainDeviceSpaprVioAddress *virDomainDeviceSpaprVioAddressPtr;
+struct _virDomainDeviceSpaprVioAddress {
+ unsigned long long reg;
+ bool has_reg;
+};
+
enum virDomainControllerMaster {
VIR_DOMAIN_CONTROLLER_MASTER_NONE,
VIR_DOMAIN_CONTROLLER_MASTER_USB,
@@ -145,6 +153,7 @@ struct _virDomainDeviceInfo {
virDomainDeviceVirtioSerialAddress vioserial;
virDomainDeviceCcidAddress ccid;
virDomainDeviceUSBAddress usb;
+ virDomainDeviceSpaprVioAddress spaprvio;
} addr;
int mastertype;
union {
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index eaef0e1..17cc972 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1253,6 +1253,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
qemuDomainPCIAddressSetPtr addrs)
def->controllers[i]->idx == 0)
continue;
+ if (def->controllers[i]->info.type ==
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO)
+ continue;
if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
continue;
if (qemuDomainPCIAddressSetNextAddr(addrs, &def->controllers[i]->info)
< 0)
@@ -1403,6 +1405,9 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
virBufferAsprintf(buf, ",bus=");
qemuUsbId(buf, info->addr.usb.bus);
virBufferAsprintf(buf, ".0,port=%s", info->addr.usb.port);
+ } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
+ if (info->addr.spaprvio.has_reg)
+ virBufferAsprintf(buf, ",reg=%#llx", info->addr.spaprvio.reg);
}
return 0;
--
1.7.7.3