Introduce apci-generic-initiator device to the domain XML.
Example definition:
<acpi-generic-initiator>
<pci-dev>dev0</pci-dev>
<numa-node>1</numa-node>
</acpi-generic-initiator>
This enables partitioning of PCI resources into multiple isolated
instances, each requiring a dedicated NUMA node definition, that can be
represented by the acpi-generic-initiator object.
Link: https://mail.gnu.org/archive/html/qemu-arm/2024-03/msg00358.html
Signed-off-by: Andrea Righi <arighi@nvidia.com>
---
docs/formatdomain.rst | 36 +++++
src/ch/ch_domain.c | 1 +
src/conf/domain_conf.c | 138 ++++++++++++++++++
src/conf/domain_conf.h | 14 ++
src/conf/domain_postparse.c | 1 +
src/conf/domain_validate.c | 37 +++++
src/conf/schemas/domaincommon.rng | 14 ++
src/conf/virconftypes.h | 2 +
src/hyperv/hyperv_driver.c | 1 +
src/libxl/libxl_driver.c | 6 +
src/lxc/lxc_driver.c | 6 +
src/qemu/qemu_alias.c | 11 ++
src/qemu/qemu_command.c | 1 +
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 +
.../acpi-generic-initiator.x86_64-latest.args | 55 +++++++
.../acpi-generic-initiator.x86_64-latest.xml | 1 +
.../acpi-generic-initiator.xml | 94 ++++++++++++
tests/qemuxmlconftest.c | 1 +
24 files changed, 439 insertions(+)
create mode 100644 tests/qemuxmlconfdata/acpi-generic-initiator.x86_64-latest.args
create mode 120000 tests/qemuxmlconfdata/acpi-generic-initiator.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/acpi-generic-initiator.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index d3c04d8b2a..3eeafade67 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9152,6 +9152,42 @@ The ``virtio`` IOMMU devices can further have ``address`` element as described
in `Device addresses`_ (address has to by type of ``pci``).
+ACPI generic initiator
+~~~~~~~~~~~~~~~~~~~~~~
+
+The ACPI Generic Initiator device (GI) allows associating a PCI device with
+a specific NUMA node in the guest through the ACPI Generic Initiator
+namespace.
+
+This is required for certain accelerator configurations, such as NVIDIA
+Multi-Instance GPU (MIG), where each virtual instance must be exposed to
+the guest as a separate NUMA node.
+
+:since:`Since v11.5.0`
+
+::
+
+ ...
+ <acpi-generic-initiator>
+ <pci-dev>dev0</pci-dev>
+ <numa-node>1</numa-node>
+ </acpi-generic-initiator>
+ ...
+
+The ``acpi-generic-initiator`` element has the following child elements:
+
+``pci-dev``
+ Mandatory. Refers to the alias of a PCI device defined in the domain
+ configuration.
+
+``numa-node``
+ Mandatory. Specifies the guest NUMA node that the PCI device should be
+ associated with through the GI mechanism.
+
+Multiple ``acpi-generic-initiator`` elements can be defined to map different PCI
+devices to different guest NUMA nodes.
+
+
Vsock
~~~~~
diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index 7231fdc49f..95d835f07f 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -164,6 +164,7 @@ chValidateDomainDeviceDef(const virDomainDeviceDef *dev,
case VIR_DOMAIN_DEVICE_CHR:
case VIR_DOMAIN_DEVICE_HOSTDEV:
case VIR_DOMAIN_DEVICE_RNG:
+ 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 cb096f2e1e..dcc0c82f70 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,
@@ -3489,6 +3490,17 @@ virDomainHostdevDefNew(void)
}
+virDomainAcpiInitiatorDef *
+virDomainAcpiInitiatorDefNew(void)
+{
+ virDomainAcpiInitiatorDef *def;
+
+ def = g_new0(virDomainAcpiInitiatorDef, 1);
+
+ return def;
+}
+
+
static virDomainTPMDef *
virDomainTPMDefNew(virDomainXMLOption *xmlopt)
{
@@ -3549,6 +3561,16 @@ void virDomainHostdevDefFree(virDomainHostdevDef *def)
g_free(def);
}
+void
+virDomainAcpiInitiatorDefFree(virDomainAcpiInitiatorDef *def)
+{
+ if (!def)
+ return;
+
+ g_free(def->pciDev);
+ g_free(def);
+}
+
void virDomainHubDefFree(virDomainHubDef *def)
{
if (!def)
@@ -3711,6 +3733,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;
@@ -4695,6 +4720,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:
@@ -4803,6 +4830,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;
@@ -5028,6 +5058,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;
@@ -5088,6 +5125,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
@@ -13671,6 +13709,49 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt,
}
+static virDomainAcpiInitiatorDef *
+virDomainAcpiInitiatorDefParseXML(virDomainXMLOption *xmlopt,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
+{
+ g_autoptr(virDomainAcpiInitiatorDef) def = virDomainAcpiInitiatorDefNew();
+ g_autofree char *tmp = NULL;
+
+ VIR_XPATH_NODE_AUTORESTORE(ctxt)
+
+ ctxt->node = node;
+
+ if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &def->info, flags) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("failed to parse device information"));
+ return NULL;
+ }
+
+ def->pciDev = virXPathString("string(./pci-dev)", ctxt);
+ if (!def->pciDev) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing initiator pci-dev"));
+ return NULL;
+ }
+
+ tmp = virXPathString("string(./numa-node)", ctxt);
+ if (tmp) {
+ if (virStrToLong_i(tmp, NULL, 10, &def->numaNode) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid value for numa-node: '%1$s'"), tmp);
+ return NULL;
+ }
+ } else {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing initiator numa-node"));
+ return NULL;
+ }
+
+ return g_steal_pointer(&def);
+}
+
+
static virDomainRedirdevDef *
virDomainRedirdevDefParseXML(virDomainXMLOption *xmlopt,
xmlNodePtr node,
@@ -14734,6 +14815,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;
@@ -20162,6 +20249,24 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
}
VIR_FREE(nodes);
+ /* analysis of the acpi generic initiator */
+ if ((n = virXPathNodeSet("./devices/acpi-generic-initiator", ctxt, &nodes)) < 0)
+ return NULL;
+
+ if (n)
+ 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;
@@ -21103,6 +21208,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)
@@ -22465,6 +22581,12 @@ 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,
@@ -22635,6 +22757,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
@@ -28920,6 +29043,17 @@ virDomainPstoreDefFormat(virBuffer *buf,
return 0;
}
+static void
+virDomainAcpiInitiatorDefFormat(virBuffer *buf,
+ virDomainAcpiInitiatorDef *acpiinitiator)
+{
+ g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
+
+ virBufferEscapeString(&childBuf, "<pci-dev>%s</pci-dev>\n", acpiinitiator->pciDev);
+ virBufferAsprintf(&childBuf, "<numa-node>%d</numa-node>\n", acpiinitiator->numaNode);
+
+ virXMLFormatElement(buf, "acpi-generic-initiator", NULL, &childBuf);
+}
int
virDomainDefFormatInternal(virDomainDef *def,
@@ -29409,6 +29543,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");
@@ -29569,6 +29706,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 984e5bfc76..6105ab956b 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,12 @@ typedef enum {
VIR_DOMAIN_STARTUP_POLICY_LAST
} virDomainStartupPolicy;
+struct _virDomainAcpiInitiatorDef {
+ char *pciDev;
+ int numaNode;
+ virDomainDeviceInfo info;
+};
+
/* basic device for direct passthrough */
struct _virDomainHostdevDef {
/* If 'parentnet' is non-NULL it means this host dev was
@@ -3296,6 +3304,9 @@ struct _virDomainDef {
size_t ntpms;
virDomainTPMDef **tpms;
+ size_t nacpiinitiator;
+ virDomainAcpiInitiatorDef **acpiinitiator;
+
/* Only 1 */
virDomainMemballoonDef *memballoon;
virDomainNVRAMDef *nvram;
@@ -3781,6 +3792,9 @@ 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);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainAcpiInitiatorDef, virDomainAcpiInitiatorDefFree);
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 a07ec8d94e..b297755477 100644
--- a/src/conf/domain_postparse.c
+++ b/src/conf/domain_postparse.c
@@ -760,6 +760,7 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDef *dev,
case VIR_DOMAIN_DEVICE_AUDIO:
case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_PSTORE:
+ case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
ret = 0;
break;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 40edecef83..675fc9f768 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2388,6 +2388,40 @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev)
}
+static int
+virDomainAcpiInitiatorDefValidate(const virDomainDef *def,
+ const virDomainAcpiInitiatorDef *acpiinitiator)
+{
+ const size_t nodeCount = virDomainNumaGetNodeCount(def->numa);
+
+ if (!nodeCount) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("No NUMA node defined"));
+ return -1;
+ }
+
+ if (acpiinitiator->numaNode >= nodeCount) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid acpi-generic-initiator NUMA node %1$u"),
+ acpiinitiator->numaNode);
+ return -1;
+ }
+
+ if (acpiinitiator->pciDev[0] == '\0') {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("acpi-generic-initiator must have a PCI device assigned"));
+ return -1;
+ }
+
+ if (acpiinitiator->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("acpi-generic-initiator must have a device address type None"));
+ return -1;
+ }
+
+ return 0;
+}
+
/**
* virDomainMemoryGetMappedSize:
* @mem: memory device definition
@@ -3328,6 +3362,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 9782dca147..cb8441aa83 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6924,6 +6924,7 @@
<ref name="shmem"/>
<ref name="memorydev"/>
<ref name="crypto"/>
+ <ref name="acpi-generic-initiator"/>
</choice>
</zeroOrMore>
<zeroOrMore>
@@ -7666,6 +7667,19 @@
</element>
</define>
+ <define name="acpi-generic-initiator">
+ <element name="acpi-generic-initiator">
+ <interleave>
+ <element name="pci-dev">
+ <ref name="aliasName"/>
+ </element>
+ <element name="numa-node">
+ <ref name="unsignedInt"/>
+ </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 93fc9c9217..ea37593980 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -122,6 +122,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/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 0c17ef16ec..7361b2fbb7 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -3124,6 +3124,7 @@ hypervDomainAttachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int
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,
_("Attaching devices of type %1$d is not implemented"), dev->type);
return -1;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 308c0372aa..1f698dc570 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3492,6 +3492,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));
@@ -3596,6 +3597,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;
@@ -3965,6 +3967,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));
@@ -4056,6 +4059,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;
@@ -4119,6 +4123,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));
@@ -4182,6 +4187,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 80cf07d2e5..51071958e8 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -3020,6 +3020,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;
@@ -3086,6 +3087,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;
@@ -3168,6 +3170,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;
@@ -3270,6 +3273,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);
@@ -3946,6 +3950,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));
@@ -4364,6 +4369,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_alias.c b/src/qemu/qemu_alias.c
index a27c688d79..a1e9e70492 100644
--- a/src/qemu/qemu_alias.c
+++ b/src/qemu/qemu_alias.c
@@ -681,6 +681,14 @@ qemuAssignDevicePstoreAlias(virDomainPstoreDef *pstore)
pstore->info.alias = g_strdup("pstore0");
}
+static void
+qemuAssignDeviceAcpiInitiatorAlias(virDomainAcpiInitiatorDef *acpiinitiator,
+ int idx)
+{
+ if (!acpiinitiator->info.alias)
+ acpiinitiator->info.alias = g_strdup_printf("gi%d", idx);
+}
+
int
qemuAssignDeviceAliases(virDomainDef *def)
@@ -773,6 +781,9 @@ qemuAssignDeviceAliases(virDomainDef *def)
}
if (def->pstore)
qemuAssignDevicePstoreAlias(def->pstore);
+ for (i = 0; i < def->nacpiinitiator; i++) {
+ qemuAssignDeviceAcpiInitiatorAlias(def->acpiinitiator[i], i);
+ }
return 0;
}
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4e4f1e87eb..cf9529dafc 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1011,6 +1011,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;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index a2c7c88a7e..6c0c41c3f4 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8820,6 +8820,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;
}
@@ -10710,6 +10711,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 96a9ca9b14..5037e4a9ea 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:
@@ -825,6 +826,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev,
return pciFlags;
}
+ case VIR_DOMAIN_DEVICE_ACPI_INITIATOR:
+ return 0;
+
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 ac72ea5cb0..36acedc1f6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6914,6 +6914,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"),
@@ -7133,6 +7134,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"),
@@ -7259,6 +7261,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 e9568af125..3376d4d2b5 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3563,6 +3563,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"),
@@ -5533,6 +5534,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;
@@ -5638,6 +5640,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"),
@@ -6540,6 +6543,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"),
@@ -7531,6 +7535,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 9c2427970d..9611f46831 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -959,6 +959,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 adba3e4a89..5ead231dd0 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -5793,6 +5793,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 25335d9002..1a086f5f47 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -10460,6 +10460,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"),
@@ -10603,6 +10604,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"),
@@ -10975,6 +10977,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"),
@@ -11046,6 +11049,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"),
diff --git a/tests/qemuxmlconfdata/acpi-generic-initiator.x86_64-latest.args b/tests/qemuxmlconfdata/acpi-generic-initiator.x86_64-latest.args
new file mode 100644
index 0000000000..1a8ac0dfc7
--- /dev/null
+++ b/tests/qemuxmlconfdata/acpi-generic-initiator.x86_64-latest.args
@@ -0,0 +1,55 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest2,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest2/master-key.aes"}' \
+-machine q35,usb=off,dump-guest-core=off,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=8388608k \
+-overcommit mem-lock=off \
+-smp 16,sockets=16,cores=1,threads=1 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node0","size":8589934592}' \
+-numa node,nodeid=0,cpus=0-15,memdev=ram-node0 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node1","size":0}' \
+-numa node,nodeid=1,memdev=ram-node1 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node2","size":0}' \
+-numa node,nodeid=2,memdev=ram-node2 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node3","size":0}' \
+-numa node,nodeid=3,memdev=ram-node3 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node4","size":0}' \
+-numa node,nodeid=4,memdev=ram-node4 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node5","size":0}' \
+-numa node,nodeid=5,memdev=ram-node5 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node6","size":0}' \
+-numa node,nodeid=6,memdev=ram-node6 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node7","size":0}' \
+-numa node,nodeid=7,memdev=ram-node7 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node8","size":0}' \
+-numa node,nodeid=8,memdev=ram-node8 \
+-uuid c7a5fdbd-edaf-9466-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \
+-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \
+-device '{"driver":"qemu-xhci","id":"usb","bus":"pci.1","addr":"0x0"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-global ICH9-LPC.noreboot=off \
+-watchdog-action reset \
+-device '{"driver":"vfio-pci","host":"0000:06:12.1","id":"hostdev0","bus":"pcie.0","addr":"0x2"}' \
+-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pcie.0","addr":"0x6"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/acpi-generic-initiator.x86_64-latest.xml b/tests/qemuxmlconfdata/acpi-generic-initiator.x86_64-latest.xml
new file mode 120000
index 0000000000..0e61738945
--- /dev/null
+++ b/tests/qemuxmlconfdata/acpi-generic-initiator.x86_64-latest.xml
@@ -0,0 +1 @@
+acpi-generic-initiator.xml
\ No newline at end of file
diff --git a/tests/qemuxmlconfdata/acpi-generic-initiator.xml b/tests/qemuxmlconfdata/acpi-generic-initiator.xml
new file mode 100644
index 0000000000..6a5485f191
--- /dev/null
+++ b/tests/qemuxmlconfdata/acpi-generic-initiator.xml
@@ -0,0 +1,94 @@
+<domain type='qemu'>
+ <name>QEMUGuest2</name>
+ <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>16</vcpu>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ <numa>
+ <cell id='0' cpus='0-15' memory='8388608' unit='KiB'/>
+ <cell id='1' memory='0' unit='KiB'/>
+ <cell id='2' memory='0' unit='KiB'/>
+ <cell id='3' memory='0' unit='KiB'/>
+ <cell id='4' memory='0' unit='KiB'/>
+ <cell id='5' memory='0' unit='KiB'/>
+ <cell id='6' memory='0' unit='KiB'/>
+ <cell id='7' memory='0' unit='KiB'/>
+ <cell id='8' memory='0' unit='KiB'/>
+ </numa>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='2' port='0x9'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='qemu-xhci'>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <hostdev mode='subsystem' type='pci' managed='yes'>
+ <source>
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x1'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </hostdev>
+ <watchdog model='itco' action='reset'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+ </memballoon>
+ <acpi-generic-initiator>
+ <pci-dev>hostdev0</pci-dev>
+ <numa-node>1</numa-node>
+ </acpi-generic-initiator>
+ <acpi-generic-initiator>
+ <pci-dev>hostdev0</pci-dev>
+ <numa-node>2</numa-node>
+ </acpi-generic-initiator>
+ <acpi-generic-initiator>
+ <pci-dev>hostdev0</pci-dev>
+ <numa-node>3</numa-node>
+ </acpi-generic-initiator>
+ <acpi-generic-initiator>
+ <pci-dev>hostdev0</pci-dev>
+ <numa-node>4</numa-node>
+ </acpi-generic-initiator>
+ <acpi-generic-initiator>
+ <pci-dev>hostdev0</pci-dev>
+ <numa-node>5</numa-node>
+ </acpi-generic-initiator>
+ <acpi-generic-initiator>
+ <pci-dev>hostdev0</pci-dev>
+ <numa-node>6</numa-node>
+ </acpi-generic-initiator>
+ <acpi-generic-initiator>
+ <pci-dev>hostdev0</pci-dev>
+ <numa-node>7</numa-node>
+ </acpi-generic-initiator>
+ <acpi-generic-initiator>
+ <pci-dev>hostdev0</pci-dev>
+ <numa-node>8</numa-node>
+ </acpi-generic-initiator>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 0d1804f101..fc906824e2 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2796,6 +2796,7 @@ mymain(void)
DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-invalid-address-type");
DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-invalid-address");
DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-dma-translation");
+ DO_TEST_CAPS_LATEST("acpi-generic-initiator");
DO_TEST_CAPS_LATEST("cpu-hotplug-startup");
DO_TEST_CAPS_ARCH_LATEST_PARSE_ERROR("cpu-hotplug-granularity", "ppc64");
--
2.50.1
© 2016 - 2025 Red Hat, Inc.