]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add address type for SPAPR VIO devices
authorMichael Ellerman <michael@ellerman.id.au>
Mon, 12 Dec 2011 23:39:31 +0000 (10:39 +1100)
committerEric Blake <eblake@redhat.com>
Tue, 20 Dec 2011 22:39:16 +0000 (15:39 -0700)
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@ellerman.id.au>
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c

index 4be8fe07f1ccfde97f8a74b262d2aa39b516603a..2897b4ae6f59eae0d1fb051a23f5543fa53d66f1 100644 (file)
@@ -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,
@@ -1961,6 +1962,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='0x%llx'", info->addr.spaprvio.reg);
+        break;
+
     default:
         virDomainReportError(VIR_ERR_INTERNAL_ERROR,
                              _("unknown address type '%d'"), info->type);
@@ -2219,6 +2225,33 @@ cleanup:
     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
 virDomainDeviceUSBMasterParseXML(xmlNodePtr node,
                                  virDomainDeviceUSBMasterPtr master)
@@ -2332,6 +2365,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,
@@ -3226,6 +3264,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"));
@@ -3618,6 +3657,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"));
index 189b8f6280086e7c901ba062977f1179ed1614c3..1f6e4420e5bf0d8567e50b6428a26d807e35dd05 100644 (file)
@@ -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 {
index 54d1694681279d472b1385e7c61425e297808eaa..02a456b78a13436bb11679c6b4dfa3e3b753eb48 100644 (file)
@@ -1256,6 +1256,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)
@@ -1406,6 +1408,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=0x%llx", info->addr.spaprvio.reg);
     }
 
     return 0;