[PATCH 2/2] qemu: Introduce acpi-generic-initiator device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Allow to define new acpi-generic-initiator objects to link a PCI device
with multiple NUMA nodes.

Link: https://mail.gnu.org/archive/html/qemu-arm/2024-03/msg00358.html
Signed-off-by: Andrea Righi <arighi@xxxxxxxxxx>
---
 src/ch/ch_domain.c                |   1 +
 src/conf/domain_conf.c            | 153 ++++++++++++++++++++++++++++++
 src/conf/domain_conf.h            |  14 +++
 src/conf/domain_postparse.c       |   1 +
 src/conf/domain_validate.c        |  40 ++++++++
 src/conf/schemas/domaincommon.rng |  19 ++++
 src/conf/virconftypes.h           |   2 +
 src/libxl/libxl_driver.c          |   6 ++
 src/lxc/lxc_driver.c              |   6 ++
 src/qemu/qemu_command.c           |  18 ++++
 src/qemu/qemu_domain.c            |   2 +
 src/qemu/qemu_domain_address.c    |   4 +
 src/qemu/qemu_driver.c            |   3 +
 src/qemu/qemu_hotplug.c           |   5 +
 src/qemu/qemu_postparse.c         |   1 +
 src/qemu/qemu_validate.c          |   1 +
 src/test/test_driver.c            |   4 +
 17 files changed, 280 insertions(+)

diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index 4f5966adce..224a97bd79 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -159,6 +159,7 @@ chValidateDomainDeviceDef(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_CONTROLLER:
     case VIR_DOMAIN_DEVICE_CHR:
     case VIR_DOMAIN_DEVICE_HOSTDEV:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         break;
 
     case VIR_DOMAIN_DEVICE_LEASE:
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 87f87bbe56..095501f77c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -342,6 +342,7 @@ VIR_ENUM_IMPL(virDomainDevice,
               "audio",
               "crypto",
               "pstore",
+              "acpiinitiator",
 );
 
 VIR_ENUM_IMPL(virDomainDiskDevice,
@@ -3457,6 +3458,19 @@ virDomainHostdevDefNew(void)
 }
 
 
+virDomainAcpiInitiatorDef *
+virDomainAcpiInitiatorDefNew(void)
+{
+    virDomainAcpiInitiatorDef *def;
+
+    def = g_new0(virDomainAcpiInitiatorDef, 1);
+
+    def->info = g_new0(virDomainDeviceInfo, 1);
+
+    return def;
+}
+
+
 static virDomainTPMDef *
 virDomainTPMDefNew(virDomainXMLOption *xmlopt)
 {
@@ -3517,6 +3531,18 @@ void virDomainHostdevDefFree(virDomainHostdevDef *def)
         g_free(def);
 }
 
+void virDomainAcpiInitiatorDefFree(virDomainAcpiInitiatorDef *def)
+{
+    if (!def)
+        return;
+
+    VIR_FREE(def->name);
+    VIR_FREE(def->pciDev);
+
+    virDomainDeviceInfoFree(def->info);
+    g_free(def);
+}
+
 void virDomainHubDefFree(virDomainHubDef *def)
 {
     if (!def)
@@ -3679,6 +3705,9 @@ void virDomainDeviceDefFree(virDomainDeviceDef *def)
     case VIR_DOMAIN_DEVICE_PSTORE:
         virDomainPstoreDefFree(def->data.pstore);
         break;
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
+        virDomainAcpiInitiatorDefFree(def->data.acpiinitiator);
+        break;
     case VIR_DOMAIN_DEVICE_LAST:
     case VIR_DOMAIN_DEVICE_NONE:
         break;
@@ -4605,6 +4634,8 @@ virDomainDeviceGetInfo(const virDomainDeviceDef *device)
         return &device->data.crypto->info;
     case VIR_DOMAIN_DEVICE_PSTORE:
         return &device->data.pstore->info;
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
+        return device->data.acpiinitiator->info;
 
     /* The following devices do not contain virDomainDeviceInfo */
     case VIR_DOMAIN_DEVICE_LEASE:
@@ -4713,6 +4744,9 @@ virDomainDeviceSetData(virDomainDeviceDef *device,
     case VIR_DOMAIN_DEVICE_PSTORE:
         device->data.pstore = devicedata;
         break;
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
+        device->data.acpiinitiator = devicedata;
+        break;
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_LAST:
         break;
@@ -4938,6 +4972,13 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def,
             return rc;
     }
 
+    device.type = VIR_DOMAIN_DEVICE_ACPI_INITIATOR;
+    for (i = 0; i < def->nacpiinitiator; i++) {
+        device.data.acpiinitiator = def->acpiinitiator[i];
+        if ((rc = cb(def, &device, def->acpiinitiator[i]->info, opaque)) != 0)
+            return rc;
+    }
+
     /* If the flag below is set, make sure @cb can handle @info being NULL */
     if (iteratorFlags & DOMAIN_DEVICE_ITERATE_MISSING_INFO) {
         device.type = VIR_DOMAIN_DEVICE_GRAPHICS;
@@ -4998,6 +5039,7 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         break;
     }
 #endif
@@ -13373,6 +13415,60 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt,
 }
 
 
+static virDomainAcpiInitiatorDef *
+virDomainAcpiInitiatorDefParseXML(virDomainXMLOption *xmlopt,
+                            xmlNodePtr node,
+                            xmlXPathContextPtr ctxt,
+                            unsigned int flags)
+{
+    virDomainAcpiInitiatorDef *def;
+    xmlNodePtr cur;
+
+    VIR_XPATH_NODE_AUTORESTORE(ctxt)
+
+    ctxt->node = node;
+
+    if (!(def = virDomainAcpiInitiatorDefNew()))
+        goto error;
+
+    for (cur = node->children; cur; cur = cur->next) {
+        if (cur->type != XML_ELEMENT_NODE)
+            continue;
+
+        if (xmlStrEqual(cur->name, BAD_CAST "alias")) {
+            def->name = virXMLPropString(cur, "name");
+            if (!def->name)
+                goto error;
+        } else if (xmlStrEqual(cur->name, BAD_CAST "pci-dev")) {
+            def->pciDev = virXMLNodeContentString(cur);
+            if (!def->pciDev)
+                goto error;
+        } else if (xmlStrEqual(cur->name, BAD_CAST "numa-node")) {
+            xmlChar *content = xmlNodeGetContent(cur);
+
+            if (!content)
+                goto error;
+            if (virStrToLong_i((const char *)content, NULL, 10, &def->numaNode) < 0) {
+                xmlFree(content);
+                goto error;
+            }
+            xmlFree(content);
+        }
+    }
+
+    if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+        if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, def->info,
+                                        flags) < 0)
+            goto error;
+    }
+    return def;
+
+ error:
+    virDomainAcpiInitiatorDefFree(def);
+    return NULL;
+}
+
+
 static virDomainRedirdevDef *
 virDomainRedirdevDefParseXML(virDomainXMLOption *xmlopt,
                              xmlNodePtr node,
@@ -14374,6 +14470,12 @@ virDomainDeviceDefParse(const char *xmlStr,
             return NULL;
         }
         break;
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
+        if (!(dev->data.acpiinitiator = virDomainAcpiInitiatorDefParseXML(xmlopt, node,
+                                                            ctxt, flags))) {
+            return NULL;
+        }
+        break;
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_LAST:
         break;
@@ -19798,6 +19900,23 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
     }
     VIR_FREE(nodes);
 
+    /* analysis of the acpi generic initiator */
+    if ((n = virXPathNodeSet("./devices/acpi-generic-initiator", ctxt, &nodes)) < 0)
+        return NULL;
+
+    def->acpiinitiator = g_new0(virDomainAcpiInitiatorDef *, n);
+
+    for (i = 0; i < n; i++) {
+        virDomainAcpiInitiatorDef *acpiinitiator;
+
+        acpiinitiator = virDomainAcpiInitiatorDefParseXML(xmlopt, nodes[i], ctxt, flags);
+        if (!acpiinitiator)
+            return NULL;
+
+        def->acpiinitiator[def->nacpiinitiator++] = acpiinitiator;
+    }
+    VIR_FREE(nodes);
+
     /* analysis of the user namespace mapping */
     if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0)
         return NULL;
@@ -20725,6 +20844,17 @@ virDomainHostdevDefCheckABIStability(virDomainHostdevDef *src,
 }
 
 
+static bool
+virDomainAcpiInitiatorDefCheckABIStability(virDomainAcpiInitiatorDef *src,
+                                     virDomainAcpiInitiatorDef *dst)
+{
+    if (!virDomainDeviceInfoCheckABIStability(src->info, dst->info))
+        return false;
+
+    return true;
+}
+
+
 static bool
 virDomainSmartcardDefCheckABIStability(virDomainSmartcardDef *src,
                                        virDomainSmartcardDef *dst)
@@ -22073,6 +22203,11 @@ virDomainDefCheckABIStabilityFlags(virDomainDef *src,
             goto error;
     }
 
+    for (i = 0; i < src->nacpiinitiator; i++) {
+        if (!virDomainAcpiInitiatorDefCheckABIStability(src->acpiinitiator[i], dst->acpiinitiator[i]))
+            goto error;
+    }
+
     if ((!src->redirfilter && dst->redirfilter) ||
         (src->redirfilter && !dst->redirfilter)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -22243,6 +22378,7 @@ virDomainDefCheckABIStabilityFlags(virDomainDef *src,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         break;
     }
 #endif
@@ -28287,6 +28423,19 @@ virDomainPstoreDefFormat(virBuffer *buf,
     return 0;
 }
 
+static void
+virDomainAcpiInitiatorDefFormat(virBuffer *buf,
+                         virDomainAcpiInitiatorDef *acpiinitiator)
+{
+    g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+    g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
+
+    virBufferAsprintf(&childBuf, "<alias name=\"%s\" />\n", acpiinitiator->name);
+    virBufferAsprintf(&childBuf, "<pci-dev>%s</pci-dev>\n", acpiinitiator->pciDev);
+    virBufferAsprintf(&childBuf, "<numa-node>%d</numa-node>\n", acpiinitiator->numaNode);
+
+    virXMLFormatElement(buf, "acpi-generic-initiator", &attrBuf, &childBuf);
+}
 
 int
 virDomainDefFormatInternal(virDomainDef *def,
@@ -28762,6 +28911,9 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
     if (def->pstore)
         virDomainPstoreDefFormat(buf, def->pstore, flags);
 
+    for (n = 0; n < def->nacpiinitiator; n++)
+        virDomainAcpiInitiatorDefFormat(buf, def->acpiinitiator[n]);
+
     virBufferAdjustIndent(buf, -2);
     virBufferAddLit(buf, "</devices>\n");
 
@@ -28922,6 +29074,7 @@ virDomainDeviceIsUSB(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     break;
     }
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e51c74b6d1..b43d589760 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -88,6 +88,7 @@ typedef enum {
     VIR_DOMAIN_DEVICE_AUDIO,
     VIR_DOMAIN_DEVICE_CRYPTO,
     VIR_DOMAIN_DEVICE_PSTORE,
+    VIR_DOMAIN_DEVICE_ACPI_INITIATOR,
 
     VIR_DOMAIN_DEVICE_LAST
 } virDomainDeviceType;
@@ -122,6 +123,7 @@ struct _virDomainDeviceDef {
         virDomainAudioDef *audio;
         virDomainCryptoDef *crypto;
         virDomainPstoreDef *pstore;
+        virDomainAcpiInitiatorDef *acpiinitiator;
     } data;
 };
 
@@ -353,6 +355,13 @@ typedef enum {
     VIR_DOMAIN_STARTUP_POLICY_LAST
 } virDomainStartupPolicy;
 
+struct _virDomainAcpiInitiatorDef {
+    char *name;
+    char *pciDev;
+    int numaNode;
+    virDomainDeviceInfo *info; /* Guest address */
+};
+
 /* basic device for direct passthrough */
 struct _virDomainHostdevDef {
     /* If 'parentnet' is non-NULL it means this host dev was
@@ -3210,6 +3219,9 @@ struct _virDomainDef {
     size_t ntpms;
     virDomainTPMDef **tpms;
 
+    size_t nacpiinitiator;
+    virDomainAcpiInitiatorDef **acpiinitiator;
+
     /* Only 1 */
     virDomainMemballoonDef *memballoon;
     virDomainNVRAMDef *nvram;
@@ -3690,6 +3702,8 @@ virDomainVideoDef *virDomainVideoDefNew(virDomainXMLOption *xmlopt);
 void virDomainVideoDefFree(virDomainVideoDef *def);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVideoDef, virDomainVideoDefFree);
 void virDomainVideoDefClear(virDomainVideoDef *def);
+virDomainAcpiInitiatorDef *virDomainAcpiInitiatorDefNew(void);
+void virDomainAcpiInitiatorDefFree(virDomainAcpiInitiatorDef *def);
 virDomainHostdevDef *virDomainHostdevDefNew(void);
 void virDomainHostdevDefFree(virDomainHostdevDef *def);
 void virDomainHubDefFree(virDomainHubDef *def);
diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c
index bf33f29638..acdfbdc679 100644
--- a/src/conf/domain_postparse.c
+++ b/src/conf/domain_postparse.c
@@ -757,6 +757,7 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_PSTORE:
         ret = 0;
         break;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index eb5e764c02..3bcbedb4fb 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2316,6 +2316,43 @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev)
 }
 
 
+static int
+virDomainAcpiInitiatorDefValidate(const virDomainDef *def,
+                                  const virDomainAcpiInitiatorDef *acpiinitiator)
+{
+    const size_t nodeCount = virDomainNumaGetNodeCount(def->numa);
+    size_t i;
+
+    if (!nodeCount) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+               _("No NUMA node defined"));
+        return -1;
+    }
+
+    for (i = 0; i < nodeCount; i++)
+        if (acpiinitiator->numaNode == i)
+            break;
+    if (i == nodeCount) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+               _("acpi-generic-initiator must have a valid NUMA node"));
+        return -1;
+    }
+
+    if (acpiinitiator->name[0] == '\0') {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+               _("acpi-generic-initiator must have a name"));
+        return -1;
+    }
+
+    if (acpiinitiator->pciDev[0] == '\0') {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+               _("acpi-generic-initiator must have a PCI device assigned"));
+        return -1;
+    }
+
+    return 0;
+}
+
 /**
  * virDomainMemoryGetMappedSize:
  * @mem: memory device definition
@@ -3234,6 +3271,9 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_PSTORE:
         return virDomainPstoreDefValidate(dev->data.pstore);
 
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
+        return virDomainAcpiInitiatorDefValidate(def, dev->data.acpiinitiator);
+
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_WATCHDOG:
     case VIR_DOMAIN_DEVICE_HUB:
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 96cedb85e8..f6c42a4844 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6807,6 +6807,7 @@
             <ref name="shmem"/>
             <ref name="memorydev"/>
             <ref name="crypto"/>
+            <ref name="acpi-generic-initiator"/>
           </choice>
         </zeroOrMore>
         <zeroOrMore>
@@ -7626,6 +7627,24 @@
     </element>
   </define>
 
+  <define name="acpi-generic-initiator">
+    <element name="acpi-generic-initiator">
+      <interleave>
+        <element name="alias">
+          <attribute name="name">
+            <text/>
+          </attribute>
+        </element>
+        <element name="pci-dev">
+          <text/>
+        </element>
+        <element name="numa-node">
+          <text/>
+        </element>
+      </interleave>
+    </element>
+  </define>
+
   <define name="crypto">
     <element name="crypto">
       <attribute name="model">
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index 59be61cea4..564c06638e 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -118,6 +118,8 @@ typedef struct _virDomainHostdevCaps virDomainHostdevCaps;
 
 typedef struct _virDomainHostdevDef virDomainHostdevDef;
 
+typedef struct _virDomainAcpiInitiatorDef virDomainAcpiInitiatorDef;
+
 typedef struct _virDomainHostdevSubsys virDomainHostdevSubsys;
 
 typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediatedDev;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index a76545c9ff..61e21dd85d 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3511,6 +3511,7 @@ libxlDomainAttachDeviceLive(libxlDriverPrivate *driver,
         case VIR_DOMAIN_DEVICE_AUDIO:
         case VIR_DOMAIN_DEVICE_CRYPTO:
         case VIR_DOMAIN_DEVICE_PSTORE:
+        case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("device type '%1$s' cannot be attached"),
                            virDomainDeviceTypeToString(dev->type));
@@ -3620,6 +3621,7 @@ libxlDomainAttachDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev)
         case VIR_DOMAIN_DEVICE_AUDIO:
         case VIR_DOMAIN_DEVICE_CRYPTO:
         case VIR_DOMAIN_DEVICE_PSTORE:
+        case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("persistent attach of device is not supported"));
             return -1;
@@ -3989,6 +3991,7 @@ libxlDomainDetachDeviceLive(libxlDriverPrivate *driver,
         case VIR_DOMAIN_DEVICE_AUDIO:
         case VIR_DOMAIN_DEVICE_CRYPTO:
         case VIR_DOMAIN_DEVICE_PSTORE:
+        case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("device type '%1$s' cannot be detached"),
                            virDomainDeviceTypeToString(dev->type));
@@ -4080,6 +4083,7 @@ libxlDomainDetachDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev)
         case VIR_DOMAIN_DEVICE_AUDIO:
         case VIR_DOMAIN_DEVICE_CRYPTO:
         case VIR_DOMAIN_DEVICE_PSTORE:
+        case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("persistent detach of device is not supported"));
             return -1;
@@ -4143,6 +4147,7 @@ libxlDomainUpdateDeviceLive(virDomainObj *vm, virDomainDeviceDef *dev)
         case VIR_DOMAIN_DEVICE_AUDIO:
         case VIR_DOMAIN_DEVICE_CRYPTO:
         case VIR_DOMAIN_DEVICE_PSTORE:
+        case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("device type '%1$s' cannot be updated"),
                            virDomainDeviceTypeToString(dev->type));
@@ -4206,6 +4211,7 @@ libxlDomainUpdateDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev)
         case VIR_DOMAIN_DEVICE_AUDIO:
         case VIR_DOMAIN_DEVICE_CRYPTO:
         case VIR_DOMAIN_DEVICE_PSTORE:
+        case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("persistent update of device is not supported"));
             return -1;
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 4740aeed52..828abc5d32 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -3024,6 +3024,7 @@ lxcDomainAttachDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
          virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                         _("persistent attach of device is not supported"));
          break;
@@ -3090,6 +3091,7 @@ lxcDomainUpdateDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("persistent update of device is not supported"));
         break;
@@ -3172,6 +3174,7 @@ lxcDomainDetachDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("persistent detach of device is not supported"));
         break;
@@ -3274,6 +3277,7 @@ lxcDomainAttachDeviceMknodHelper(pid_t pid G_GNUC_UNUSED,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Unexpected device type %1$d"),
                        data->def->type);
@@ -3950,6 +3954,7 @@ lxcDomainAttachDeviceLive(virLXCDriver *driver,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("device type '%1$s' cannot be attached"),
                        virDomainDeviceTypeToString(dev->type));
@@ -4368,6 +4373,7 @@ lxcDomainDetachDeviceLive(virLXCDriver *driver,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("device type '%1$s' cannot be detached"),
                        virDomainDeviceTypeToString(dev->type));
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 03d0676f45..0619e2b132 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -991,6 +991,7 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device,
         case VIR_DOMAIN_DEVICE_IOMMU:
         case VIR_DOMAIN_DEVICE_AUDIO:
         case VIR_DOMAIN_DEVICE_PSTORE:
+        case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         case VIR_DOMAIN_DEVICE_LAST:
         default:
             break;
@@ -10290,6 +10291,18 @@ qemuBuildPstoreCommandLine(virCommand *cmd,
     return 0;
 }
 
+static int
+qemuBuildAcpiInitiatorCommandLine(virCommand *cmd,
+                                  const virDomainAcpiInitiatorDef *acpiinitiator)
+{
+    g_autofree char *obj = NULL;
+
+    obj = g_strdup_printf("acpi-generic-initiator,id=%s,pci-dev=%s,node=%d",
+                          acpiinitiator->name, acpiinitiator->pciDev, acpiinitiator->numaNode);
+    virCommandAddArgList(cmd, "-object", obj, NULL);
+
+    return 0;
+}
 
 static int
 qemuBuildAsyncTeardownCommandLine(virCommand *cmd,
@@ -10656,6 +10669,11 @@ qemuBuildCommandLine(virDomainObj *vm,
         qemuBuildPstoreCommandLine(cmd, def, def->pstore, qemuCaps) < 0)
         return NULL;
 
+    for (i = 0; i < def->nacpiinitiator; i++) {
+        if (qemuBuildAcpiInitiatorCommandLine(cmd, def->acpiinitiator[i]) < 0)
+            return NULL;
+    }
+
     if (qemuBuildAsyncTeardownCommandLine(cmd, def, qemuCaps) < 0)
         return NULL;
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index cf05dca55a..36782b381e 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8721,6 +8721,7 @@ qemuDomainPrepareChardevSourceOne(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         break;
     }
 
@@ -10655,6 +10656,7 @@ qemuDomainDeviceBackendChardevForeachOne(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         /* no chardev backend */
         break;
     }
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 970ae3949d..aac0ca7ece 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -471,6 +471,7 @@ qemuDomainDeviceSupportZPCI(virDomainDeviceDef *device)
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         break;
 
     case VIR_DOMAIN_DEVICE_NONE:
@@ -819,6 +820,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev,
         return pciFlags;
     }
 
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
+        return pciFlags;
+
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
         switch (dev->data.memballoon->model) {
         case VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO_TRANSITIONAL:
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 78bfaa5b3a..ada49fb389 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6899,6 +6899,7 @@ qemuDomainAttachDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
          virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                         _("persistent attach of device '%1$s' is not supported"),
@@ -7118,6 +7119,7 @@ qemuDomainDetachDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("persistent detach of device '%1$s' is not supported"),
@@ -7244,6 +7246,7 @@ qemuDomainUpdateDeviceConfig(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("persistent update of device '%1$s' is not supported"),
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6c224c9793..089e5d9aad 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3521,6 +3521,7 @@ qemuDomainAttachDeviceLive(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live attach of device '%1$s' is not supported"),
@@ -5440,6 +5441,7 @@ qemuDomainRemoveAuditDevice(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         /* libvirt doesn't yet support detaching these devices */
         break;
@@ -5545,6 +5547,7 @@ qemuDomainRemoveDevice(virQEMUDriver *driver,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("don't know how to remove a %1$s device"),
@@ -6440,6 +6443,7 @@ qemuDomainDetachDeviceLive(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live detach of device '%1$s' is not supported"),
@@ -7432,6 +7436,7 @@ qemuDomainUpdateDeviceLive(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("live update of device '%1$s' is not supported"),
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
index 20ee333e0d..c81f93e384 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -905,6 +905,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_RNG:
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
         ret = 0;
         break;
 
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 76f2eafe49..ddd067c331 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -5498,6 +5498,7 @@ qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_PSTORE:
         return qemuValidateDomainDeviceDefPstore(dev->data.pstore, def, qemuCaps);
 
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_NONE:
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 6f18b2b2c8..5c706a1035 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -10459,6 +10459,7 @@ testDomainAttachDeviceLive(virDomainObj *vm,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live attach of device '%1$s' is not supported"),
@@ -10602,6 +10603,7 @@ testDomainUpdateDevice(virDomainDef *vmdef,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("persistent update of device '%1$s' is not supported"),
@@ -10973,6 +10975,7 @@ testDomainRemoveDevice(testDriver *driver,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live detach of device '%1$s' is not supported"),
@@ -11044,6 +11047,7 @@ testDomainDetachDeviceLive(testDriver *driver,
     case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_CRYPTO:
     case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live detach of device '%1$s' is not supported"),
-- 
2.48.1




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux