]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: Add nodeset attribute to the <acpi> element
authorAndrea Righi <arighi@nvidia.com>
Sat, 6 Sep 2025 13:08:58 +0000 (15:08 +0200)
committerDaniel P. Berrangé <berrange@redhat.com>
Mon, 8 Sep 2025 18:12:35 +0000 (19:12 +0100)
This enables partitioning of PCI devices into multiple isolated
instances, each requiring a dedicated virtual NUMA node definition.

Link: https://mail.gnu.org/archive/html/qemu-arm/2024-03/msg00358.html
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Andrea Righi <arighi@nvidia.com>
src/conf/device_conf.c
src/conf/device_conf.h
src/conf/domain_conf.c
src/conf/schemas/domaincommon.rng

index f840efc1b5624caa4ee2ca1db7177b6288daf7f9..d08de68717a38dfab5bf5af94bdb454e1d9e9bf7 100644 (file)
@@ -137,6 +137,7 @@ virDomainDeviceInfoClear(virDomainDeviceInfo *info)
     info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE;
     VIR_FREE(info->romfile);
     VIR_FREE(info->loadparm);
+    virBitmapFree(info->acpiNodeset);
     info->isolationGroup = 0;
     info->isolationGroupLocked = false;
 }
index 2d97410f6e214785a3bef73d5590f9000665eb35..e570f518242f313a7bafd24251cbe5420d647f6f 100644 (file)
@@ -185,6 +185,9 @@ struct _virDomainDeviceInfo {
      * cases we might want to prevent that from happening by
      * locking the isolation group */
     bool isolationGroupLocked;
+
+    /* NUMA nodeset affinity for this device */
+    virBitmap *acpiNodeset;
 };
 
 int virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node,
index 7766e302ec7c3b17a5ec39f655ace76e0b45ccfe..8c0bf6392559acff22945989cdac479959f31b8d 100644 (file)
@@ -5558,8 +5558,20 @@ virDomainDeviceInfoFormat(virBuffer *buf,
         virBufferAddLit(buf, "/>\n");
     }
 
-    if (info->acpiIndex != 0)
-        virBufferAsprintf(buf, "<acpi index='%u'/>\n", info->acpiIndex);
+    if (info->acpiIndex != 0 || info->acpiNodeset) {
+        virBufferAddLit(buf, "<acpi");
+
+        if (info->acpiIndex != 0)
+            virBufferAsprintf(buf, " index='%u'", info->acpiIndex);
+
+        if (info->acpiNodeset) {
+            g_autofree char *nodeset = virBitmapFormat(info->acpiNodeset);
+            if (nodeset)
+                virBufferAsprintf(buf, " nodeset='%s'", nodeset);
+        }
+
+        virBufferAddLit(buf, "/>\n");
+    }
 
     if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
         info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
@@ -5884,9 +5896,23 @@ virDomainDeviceInfoParseXML(virDomainXMLOption *xmlopt,
     }
 
     if ((acpi = virXPathNode("./acpi", ctxt))) {
+        g_autofree char *nodeset = NULL;
+
         if (virXMLPropUInt(acpi, "index", 10, VIR_XML_PROP_NONZERO,
                            &info->acpiIndex) < 0)
             goto cleanup;
+
+        if ((nodeset = virXMLPropString(acpi, "nodeset"))) {
+            if (virBitmapParse(nodeset, &info->acpiNodeset,
+                               VIR_DOMAIN_CPUMASK_LEN) < 0)
+                goto cleanup;
+
+            if (virBitmapIsAllClear(info->acpiNodeset)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("Invalid value of 'nodeset': %1$s"), nodeset);
+                goto cleanup;
+            }
+        }
     }
 
     if ((address = virXPathNode("./address", ctxt)) &&
index e369fb6e81c647959a14ae5792c0cf014b21ed3a..298afe0b7c47444a29fb407088a8e9b42cdc91db 100644 (file)
           <ref name="unsignedInt"/>
         </attribute>
       </optional>
+      <optional>
+        <attribute name="nodeset">
+          <ref name="cpuset"/>
+        </attribute>
+      </optional>
     </element>
   </define>