提交 7e4d896b 编写于 作者: M Michael Ellerman 提交者: Eric Blake

Add address type for SPAPR VIO devices

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: NMichael Ellerman <michael@ellerman.id.au>
上级 fbdfda14
...@@ -139,7 +139,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, ...@@ -139,7 +139,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"drive", "drive",
"virtio-serial", "virtio-serial",
"ccid", "ccid",
"usb") "usb",
"spapr-vio")
VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti, VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti,
VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST, VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST,
...@@ -1961,6 +1962,11 @@ virDomainDeviceInfoFormat(virBufferPtr buf, ...@@ -1961,6 +1962,11 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
info->addr.usb.port); info->addr.usb.port);
break; break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO:
if (info->addr.spaprvio.has_reg)
virBufferAsprintf(buf, " reg='0x%llx'", info->addr.spaprvio.reg);
break;
default: default:
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown address type '%d'"), info->type); _("unknown address type '%d'"), info->type);
...@@ -2219,6 +2225,33 @@ cleanup: ...@@ -2219,6 +2225,33 @@ cleanup:
return ret; return ret;
} }
static int
virDomainDeviceSpaprVioAddressParseXML(xmlNodePtr node,
virDomainDeviceSpaprVioAddressPtr addr)
{
char *reg;
int ret;
memset(addr, 0, sizeof(*addr));
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 static int
virDomainDeviceUSBMasterParseXML(xmlNodePtr node, virDomainDeviceUSBMasterParseXML(xmlNodePtr node,
virDomainDeviceUSBMasterPtr master) virDomainDeviceUSBMasterPtr master)
...@@ -2332,6 +2365,11 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, ...@@ -2332,6 +2365,11 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
goto cleanup; goto cleanup;
break; break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO:
if (virDomainDeviceSpaprVioAddressParseXML(address, &info->addr.spaprvio) < 0)
goto cleanup;
break;
default: default:
/* Should not happen */ /* Should not happen */
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
...@@ -3226,6 +3264,7 @@ virDomainControllerDefParseXML(xmlNodePtr node, ...@@ -3226,6 +3264,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_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"));
...@@ -3618,6 +3657,7 @@ virDomainNetDefParseXML(virCapsPtr caps, ...@@ -3618,6 +3657,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
/* XXX what about ISA/USB based NIC models - once we support /* XXX what about ISA/USB based NIC models - once we support
* 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_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"));
......
...@@ -69,6 +69,7 @@ enum virDomainDeviceAddressType { ...@@ -69,6 +69,7 @@ enum virDomainDeviceAddressType {
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL,
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_LAST VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
}; };
...@@ -121,6 +122,13 @@ struct _virDomainDeviceUSBAddress { ...@@ -121,6 +122,13 @@ struct _virDomainDeviceUSBAddress {
char *port; char *port;
}; };
typedef struct _virDomainDeviceSpaprVioAddress virDomainDeviceSpaprVioAddress;
typedef virDomainDeviceSpaprVioAddress *virDomainDeviceSpaprVioAddressPtr;
struct _virDomainDeviceSpaprVioAddress {
unsigned long long reg;
bool has_reg;
};
enum virDomainControllerMaster { enum virDomainControllerMaster {
VIR_DOMAIN_CONTROLLER_MASTER_NONE, VIR_DOMAIN_CONTROLLER_MASTER_NONE,
VIR_DOMAIN_CONTROLLER_MASTER_USB, VIR_DOMAIN_CONTROLLER_MASTER_USB,
...@@ -145,6 +153,7 @@ struct _virDomainDeviceInfo { ...@@ -145,6 +153,7 @@ struct _virDomainDeviceInfo {
virDomainDeviceVirtioSerialAddress vioserial; virDomainDeviceVirtioSerialAddress vioserial;
virDomainDeviceCcidAddress ccid; virDomainDeviceCcidAddress ccid;
virDomainDeviceUSBAddress usb; virDomainDeviceUSBAddress usb;
virDomainDeviceSpaprVioAddress spaprvio;
} addr; } addr;
int mastertype; int mastertype;
union { union {
......
...@@ -1256,6 +1256,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) ...@@ -1256,6 +1256,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
def->controllers[i]->idx == 0) def->controllers[i]->idx == 0)
continue; 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) if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
continue; continue;
if (qemuDomainPCIAddressSetNextAddr(addrs, &def->controllers[i]->info) < 0) if (qemuDomainPCIAddressSetNextAddr(addrs, &def->controllers[i]->info) < 0)
...@@ -1406,6 +1408,9 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, ...@@ -1406,6 +1408,9 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
virBufferAsprintf(buf, ",bus="); virBufferAsprintf(buf, ",bus=");
qemuUsbId(buf, info->addr.usb.bus); qemuUsbId(buf, info->addr.usb.bus);
virBufferAsprintf(buf, ".0,port=%s", info->addr.usb.port); 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=0x%llx", info->addr.spaprvio.reg);
} }
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册