]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Introduce privateData for hostdevs
authorNathan Chen <nathanc@nvidia.com>
Fri, 30 Jan 2026 18:59:13 +0000 (10:59 -0800)
committerPavel Hrdina <phrdina@redhat.com>
Mon, 2 Feb 2026 13:12:30 +0000 (14:12 +0100)
Introduce private data for hostdevs and allocate hostdev
private data by default.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
src/bhyve/bhyve_parse_command.c
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libxl/xen_common.c
src/libxl/xen_xl.c
src/lxc/lxc_native.c
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/vbox/vbox_common.c
tests/virhostdevtest.c

index d62ea64beb544cfea78f7f881fcd8d4c0a957526..8b405206bd8c8501a2427ad9f1b2482856b0c02a 100644 (file)
@@ -687,7 +687,7 @@ bhyveParsePassthru(virDomainDef *def G_GNUC_UNUSED,
         return -1;
     }
 
-    hostdev = virDomainHostdevDefNew();
+    hostdev = virDomainHostdevDefNew(NULL);
     hostdev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
     hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
 
index 016750b059449f21820179340844fb7ac931746f..02e23f78667a775637c710b651ba5fc7a127226f 100644 (file)
@@ -2734,6 +2734,8 @@ virDomainHostdevDefClear(virDomainHostdevDef *def)
     case VIR_DOMAIN_HOSTDEV_MODE_LAST:
         break;
     }
+
+    g_clear_pointer(&def->privateData, virObjectUnref);
 }
 
 
@@ -3484,7 +3486,7 @@ void virDomainVideoDefFree(virDomainVideoDef *def)
 
 
 virDomainHostdevDef *
-virDomainHostdevDefNew(void)
+virDomainHostdevDefNew(virDomainXMLOption *xmlopt)
 {
     virDomainHostdevDef *def;
 
@@ -3492,6 +3494,13 @@ virDomainHostdevDefNew(void)
 
     def->info = g_new0(virDomainDeviceInfo, 1);
 
+    if (xmlopt && xmlopt->privateData.hostdevNew &&
+        !(def->privateData = xmlopt->privateData.hostdevNew())) {
+        VIR_FREE(def->info);
+        VIR_FREE(def);
+        return NULL;
+    }
+
     return def;
 }
 
@@ -13682,7 +13691,7 @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt,
 
     ctxt->node = node;
 
-    def = virDomainHostdevDefNew();
+    def = virDomainHostdevDefNew(xmlopt);
 
     if (virXMLPropEnumDefault(node, "mode", virDomainHostdevModeTypeFromString,
                               VIR_XML_PROP_NONE,
index 10ce7a2972985606a74d91a31847cbfafc83044c..66dc4e3417b8cb5bce60217a4e529add61149962 100644 (file)
@@ -364,6 +364,8 @@ struct _virDomainHostdevDef {
      */
     virDomainNetDef *parentnet;
 
+    virObject *privateData;
+
     virDomainHostdevMode mode;
     virDomainStartupPolicy startupPolicy;
     bool managed;
@@ -3589,6 +3591,7 @@ struct _virDomainXMLPrivateDataCallbacks {
     virDomainXMLPrivateDataNewFunc    vsockNew;
     virDomainXMLPrivateDataNewFunc    cryptoNew;
     virDomainXMLPrivateDataNewFunc    graphicsNew;
+    virDomainXMLPrivateDataNewFunc    hostdevNew;
     virDomainXMLPrivateDataNewFunc    networkNew;
     virDomainXMLPrivateDataNetParseFunc networkParse;
     virDomainXMLPrivateDataNetFormatFunc networkFormat;
@@ -3798,7 +3801,7 @@ virDomainVideoDef *virDomainVideoDefNew(virDomainXMLOption *xmlopt);
 void virDomainVideoDefFree(virDomainVideoDef *def);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVideoDef, virDomainVideoDefFree);
 void virDomainVideoDefClear(virDomainVideoDef *def);
-virDomainHostdevDef *virDomainHostdevDefNew(void);
+virDomainHostdevDef *virDomainHostdevDefNew(virDomainXMLOption *xmlopt);
 void virDomainHostdevDefFree(virDomainHostdevDef *def);
 void virDomainHubDefFree(virDomainHubDef *def);
 void virDomainRedirdevDefFree(virDomainRedirdevDef *def);
index 890ef1172312548fee7198ebfcf9e2f1dd133691..e6a372e07873ab7c0ae7847c2c4404b201fa0c5f 100644 (file)
@@ -445,7 +445,7 @@ xenParsePCI(char *entry)
         }
     }
 
-    hostdev = virDomainHostdevDefNew();
+    hostdev = virDomainHostdevDefNew(NULL);
     hostdev->managed = false;
     hostdev->writeFiltering = filtered;
     hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
index e72e7d7f44c06a296f978ee4986b54bb905cb691..42e1408cf31722d99dfd837776b60898e461b4f9 100644 (file)
@@ -930,7 +930,7 @@ xenParseXLUSB(virConf *conf, virDomainDef *def)
                 key = nextkey;
             }
 
-            hostdev = virDomainHostdevDefNew();
+            hostdev = virDomainHostdevDefNew(NULL);
             hostdev->managed = false;
             hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
             hostdev->source.subsys.u.usb.bus = busNum;
index 77008044293beb0aba5a7f8ec31c93a4440c96e3..a94427b0273969fd2ad4b051016649ba802a48be 100644 (file)
@@ -376,7 +376,7 @@ lxcCreateNetDef(const char *type,
 static virDomainHostdevDef *
 lxcCreateHostdevDef(const char *data)
 {
-    virDomainHostdevDef *hostdev = virDomainHostdevDefNew();
+    virDomainHostdevDef *hostdev = virDomainHostdevDefNew(NULL);
     hostdev->mode = VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES;
     hostdev->source.caps.type = VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET;
     hostdev->source.caps.u.net.ifname = g_strdup(data);
index 486a0e791397dfaf9cd801a85a0a7c30347a1a55..336621467751e996dd8d777dc98619b73c5f7886 100644 (file)
@@ -1238,6 +1238,45 @@ qemuDomainNetworkPrivateFormat(const virDomainNetDef *net,
 }
 
 
+static virClass *qemuDomainHostdevPrivateClass;
+
+static void
+qemuDomainHostdevPrivateDispose(void *obj)
+{
+    qemuDomainHostdevPrivate *priv = obj;
+
+    VIR_FORCE_CLOSE(priv->vfioDeviceFd);
+}
+
+
+static int
+qemuDomainHostdevPrivateOnceInit(void)
+{
+    if (!VIR_CLASS_NEW(qemuDomainHostdevPrivate, virClassForObject()))
+        return -1;
+
+    return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(qemuDomainHostdevPrivate);
+
+virObject *
+qemuDomainHostdevPrivateNew(void)
+{
+    qemuDomainHostdevPrivate *priv;
+
+    if (qemuDomainHostdevPrivateInitialize() < 0)
+        return NULL;
+
+    if (!(priv = virObjectNew(qemuDomainHostdevPrivateClass)))
+        return NULL;
+
+    priv->vfioDeviceFd = -1;
+
+    return (virObject *) priv;
+}
+
+
 /* qemuDomainSecretInfoSetup:
  * @priv: pointer to domain private object
  * @alias: alias of the secret
@@ -3563,6 +3602,7 @@ virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks = {
     .chrSourceNew = qemuDomainChrSourcePrivateNew,
     .vsockNew = qemuDomainVsockPrivateNew,
     .graphicsNew = qemuDomainGraphicsPrivateNew,
+    .hostdevNew = qemuDomainHostdevPrivateNew,
     .networkNew = qemuDomainNetworkPrivateNew,
     .networkParse = qemuDomainNetworkPrivateParse,
     .networkFormat = qemuDomainNetworkPrivateFormat,
index b9bb3386823992d79895da68224506ad7dc2adc3..88c8416aa442427e6459a26ed174d0572a859db2 100644 (file)
@@ -461,6 +461,18 @@ struct _qemuDomainTPMPrivate {
 };
 
 
+#define QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev) \
+    ((qemuDomainHostdevPrivate *) (hostdev)->privateData)
+
+typedef struct _qemuDomainHostdevPrivate qemuDomainHostdevPrivate;
+struct _qemuDomainHostdevPrivate {
+    virObject parent;
+
+    /* VFIO device file descriptor for iommufd passthrough */
+    int vfioDeviceFd;
+};
+
+
 void
 qemuDomainNetworkPrivateClearFDs(qemuDomainNetworkPrivate *priv);
 
@@ -1175,3 +1187,6 @@ qemuDomainCheckCPU(virArch arch,
 bool
 qemuDomainMachineSupportsFloppy(const char *machine,
                                 virQEMUCaps *qemuCaps);
+
+virObject *
+qemuDomainHostdevPrivateNew(void);
index 26c5fdfef68aae24558110af7970eddb48c26b30..d2a8cf8da4edd993e11e5c35d29d2a800ba49e37 100644 (file)
@@ -3090,7 +3090,7 @@ vboxHostDeviceGetXMLDesc(struct _vboxDriver *data, virDomainDef *def, IMachine *
     def->hostdevs = g_new0(virDomainHostdevDef *, def->nhostdevs);
 
     for (i = 0; i < def->nhostdevs; i++)
-        def->hostdevs[i] = virDomainHostdevDefNew();
+        def->hostdevs[i] = virDomainHostdevDefNew(NULL);
 
     for (i = 0; i < deviceFilters.count; i++) {
         PRBool active = PR_FALSE;
index aec474a148c6750a8d9c0582e2b6c799699ebb01..a35c1d94026927ecb6eab900632e9ec4b0718bc0 100644 (file)
@@ -124,7 +124,7 @@ myInit(void)
 
     for (i = 0; i < nhostdevs; i++) {
         virDomainHostdevSubsys *subsys;
-        hostdevs[i] = virDomainHostdevDefNew();
+        hostdevs[i] = virDomainHostdevDefNew(NULL);
         if (!hostdevs[i])
             goto cleanup;
         hostdevs[i]->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;