From dad5203ccef4ef9321034a4234ea82af6d945af3 Mon Sep 17 00:00:00 2001 Message-ID: From: Pavel Hrdina Date: Thu, 26 Feb 2026 10:18:23 +0100 Subject: [PATCH] domain_conf: initialize network hostdev private data From: Pavel Hrdina Currently virDomainNetDef and virDomainActualNetDef use virDomainHostdevDef directly as structure and the code doesn't call virDomainHostdevDefNew() that would initialize private data. This is hackish quick fix to solve a crash that happens in two scenarios: 1. attaching any interface with hostdev backend 0x0000fffbfc0e2a90 in qemuDomainAttachHostPCIDevice (driver=0xfffbb4006750, vm=0xfffbf001f790, hostdev=0xfffbf400b150) at ../src/qemu/qemu_hotplug.c:1652 1652 if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, priv->mon)) < 0) 2. starting VM with interface with hostdev backend using iommufd 0x00007f6638d5b9ca in qemuProcessOpenVfioDeviceFd (hostdev=hostdev@entry=0x7f6634425ee0) at ../src/qemu/qemu_process.c:7719 7719 hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFd); Proper fix for this issue is to refactor network code to use pointer and to use virDomainHostdevDefNew(). Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa (cherry picked from commit fe782ed334ea0d4373e6dad093f5815fc925a56b) https://issues.redhat.com/browse/VOYAGER-227 Signed-off-by: Pavel Hrdina --- src/conf/domain_conf.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b8c180e72d..4e12ebf712 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3489,6 +3489,20 @@ void virDomainVideoDefFree(virDomainVideoDef *def) } +static int +virDomainHostdevDefPrivateDataNew(virDomainHostdevDef *def, + virDomainXMLOption *xmlopt) +{ + if (!xmlopt || !xmlopt->privateData.hostdevNew) + return 0; + + if (!(def->privateData = xmlopt->privateData.hostdevNew())) + return -1; + + return 0; +} + + virDomainHostdevDef * virDomainHostdevDefNew(virDomainXMLOption *xmlopt) { @@ -3498,8 +3512,7 @@ virDomainHostdevDefNew(virDomainXMLOption *xmlopt) def->info = g_new0(virDomainDeviceInfo, 1); - if (xmlopt && xmlopt->privateData.hostdevNew && - !(def->privateData = xmlopt->privateData.hostdevNew())) { + if (virDomainHostdevDefPrivateDataNew(def, xmlopt) < 0) { VIR_FREE(def->info); VIR_FREE(def); return NULL; @@ -9653,6 +9666,9 @@ virDomainActualNetDefParseXML(xmlNodePtr node, virDomainHostdevDef *hostdev = &actual->data.hostdev.def; int type; + if (virDomainHostdevDefPrivateDataNew(hostdev, xmlopt) < 0) + goto error; + hostdev->parentnet = parent; hostdev->info = &parent->info; /* The helper function expects type to already be found and @@ -10346,6 +10362,9 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, g_autofree char *addrtype = virXPathString("string(./source/address/@type)", ctxt); int type; + if (virDomainHostdevDefPrivateDataNew(&def->data.hostdev.def, xmlopt) < 0) + return NULL; + def->data.hostdev.def.parentnet = def; def->data.hostdev.def.info = &def->info; def->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; -- 2.53.0