From nobody Mon Feb 9 22:39:47 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=linux.ibm.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1530163513399606.4933315370826; Wed, 27 Jun 2018 22:25:13 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0E0D781107; Thu, 28 Jun 2018 05:25:12 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C42003793; Thu, 28 Jun 2018 05:25:11 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 6AB6418037F2; Thu, 28 Jun 2018 05:25:11 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w5S5OtZp023709 for ; Thu, 28 Jun 2018 01:24:55 -0400 Received: by smtp.corp.redhat.com (Postfix) id 8FE4F30001E9; Thu, 28 Jun 2018 05:24:55 +0000 (UTC) Received: from mx1.redhat.com (ext-mx06.extmail.prod.ext.phx2.redhat.com [10.5.110.30]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 880B43083323 for ; Thu, 28 Jun 2018 05:24:52 +0000 (UTC) Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 72EA1356C4 for ; Thu, 28 Jun 2018 05:24:51 +0000 (UTC) Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w5S5OgfL160827 for ; Thu, 28 Jun 2018 01:24:50 -0400 Received: from e32.co.us.ibm.com (e32.co.us.ibm.com [32.97.110.150]) by mx0b-001b2d01.pphosted.com with ESMTP id 2jvs2118t9-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 28 Jun 2018 01:24:50 -0400 Received: from localhost by e32.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 27 Jun 2018 23:24:49 -0600 Received: from b03cxnp08026.gho.boulder.ibm.com (9.17.130.18) by e32.co.us.ibm.com (192.168.1.132) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 27 Jun 2018 23:24:47 -0600 Received: from b03ledav002.gho.boulder.ibm.com (b03ledav002.gho.boulder.ibm.com [9.17.130.233]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w5S5OjIq8978928 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 27 Jun 2018 22:24:46 -0700 Received: from b03ledav002.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CDDDF13605D; Wed, 27 Jun 2018 23:24:45 -0600 (MDT) Received: from b03ledav002.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C8684136055; Wed, 27 Jun 2018 23:24:43 -0600 (MDT) Received: from zyimindembp.cn.ibm.com (unknown [9.115.193.6]) by b03ledav002.gho.boulder.ibm.com (Postfix) with ESMTP; Wed, 27 Jun 2018 23:24:43 -0600 (MDT) From: Yi Min Zhao To: libvir-list@redhat.com Date: Thu, 28 Jun 2018 13:24:09 +0800 In-Reply-To: <20180628052413.88885-1-zyimin@linux.ibm.com> References: <20180628052413.88885-1-zyimin@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18062805-0004-0000-0000-0000145B098B X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009268; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000266; SDB=6.01053394; UDB=6.00540104; IPR=6.00831316; MB=3.00021897; MTD=3.00000008; XFM=3.00000015; UTC=2018-06-28 05:24:49 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18062805-0005-0000-0000-000087E4C6B1 Message-Id: <20180628052413.88885-9-zyimin@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-06-28_02:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1806210000 definitions=main-1806280059 X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 28 Jun 2018 05:24:51 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 28 Jun 2018 05:24:51 +0000 (UTC) for IP:'148.163.158.5' DOMAIN:'mx0b-001b2d01.pphosted.com' HELO:'mx0a-001b2d01.pphosted.com' FROM:'zyimin@linux.ibm.com' RCPT:'' X-RedHat-Spam-Score: -0.701 (RCVD_IN_DNSWL_LOW, SPF_PASS) 148.163.158.5 mx0b-001b2d01.pphosted.com 148.163.158.5 mx0b-001b2d01.pphosted.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.30 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.26 X-loop: libvir-list@redhat.com Cc: fiuczy@linux.ibm.com, jtomko@redhat.com, cohuck@redhat.com, ptoscano@redhat.com, renxiaof@linux.vnet.ibm.com, bwalk@linux.ibm.com, laine@laine.org Subject: [libvirt] [PATCH v2 08/12] conf: Allocate/release 'uid' and 'fid' in PCI address X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 28 Jun 2018 05:25:12 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This patch adds new functions for reservation, assignment and release to handle the uid/fid. If the uid/fid is defined in the domain XML, they will be reserved directly in collecting phase. If any of them is not defined, we will find out an available value for it from zPCI address hashtable, and reserve it. For hotplug case, there might be or not zPCI definition. So allocate and reserve uid/fid for undefined case. Assign if needed and reserve uid/fid for defined case. If the user define zPCI extension address but zPCI capability doesn't exist, an error will be reported. Signed-off-by: Yi Min Zhao Reviewed-by: Boris Fiuczynski --- src/conf/domain_addr.c | 264 +++++++++++++++++++++++++++++++++++++= ++++ src/conf/domain_addr.h | 15 +++ src/libvirt_private.syms | 3 + src/qemu/qemu_domain_address.c | 41 ++++++- 4 files changed, 321 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 37a3645c5d..c196323c53 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -33,6 +33,147 @@ =20 VIR_LOG_INIT("conf.domain_addr"); =20 +static int +virDomainZPCIAddressReserveId(virHashTablePtr set, unsigned int id, + const char *name) +{ + if (virHashLookup(set, &id)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("zPCI %s %u is already reserved"), name, id); + return -1; + } + + if (virHashAddEntry(set, &id, (void*)1) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to reserve %s %u"), name, id); + return -1; + } + + return 0; +} + +static int +virDomainZPCIAddressReserveUid(virHashTablePtr set, virZPCIDeviceAddressPt= r addr) +{ + return virDomainZPCIAddressReserveId(set, addr->zpci_uid, "uid"); +} + +static int +virDomainZPCIAddressReserveFid(virHashTablePtr set, virZPCIDeviceAddressPt= r addr) +{ + return virDomainZPCIAddressReserveId(set, addr->zpci_fid, "fid"); +} + + +static bool +virDomainZPCIAddressAssignId(virHashTablePtr set, unsigned int *id, + unsigned int min, unsigned int max, + const char *name) +{ + while (virHashLookup(set, &min)) { + if (min =3D=3D max) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("There is no more free %s."), name); + return false; + } + ++min; + } + *id =3D min; + + return true; +} + +static int +virDomainZPCIAddressAssignUid(virHashTablePtr set, virZPCIDeviceAddressPtr= addr) +{ + if (addr->uid_assigned) + return 0; + + addr->uid_assigned =3D virDomainZPCIAddressAssignId(set, &addr->zpci_u= id, 1, + VIR_DOMAIN_DEVICE_ZPCI_MAX_UID, "ui= d"); + return addr->uid_assigned ? 0 : -1; +} + +static int +virDomainZPCIAddressAssignFid(virHashTablePtr set, virZPCIDeviceAddressPtr= addr) +{ + if (addr->fid_assigned) + return 0; + + addr->fid_assigned =3D virDomainZPCIAddressAssignId(set, &addr->zpci_f= id, 0, + VIR_DOMAIN_DEVICE_ZPCI_MAX_FID, "fi= d"); + return addr->fid_assigned ? 0 : -1; +} + + +static void +virDomainZPCIAddressReleaseUid(virHashTablePtr set, virZPCIDeviceAddressPt= r addr) +{ + if (!addr->uid_assigned) + return; + + if (virHashRemoveEntry(set, &addr->zpci_uid)) + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Release uid %u failed"), addr->zpci_uid); + + addr->uid_assigned =3D false; +} + +static void +virDomainZPCIAddressReleaseFid(virHashTablePtr set, virZPCIDeviceAddressPt= r addr) +{ + if (!addr->fid_assigned) + return; + + if (virHashRemoveEntry(set, &addr->zpci_fid)) + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Release fid %u failed"), addr->zpci_fid); + + addr->fid_assigned =3D false; +} + + +static void +virDomainZPCIAddressReleaseIds(virDomainZPCIAddressIdsPtr zpciIds, + virPCIDeviceAddressPtr addr) +{ + if (!zpciIds || !addr->zpci) + return; + + virDomainZPCIAddressReleaseUid(zpciIds->uids, addr->zpci); + + virDomainZPCIAddressReleaseFid(zpciIds->fids, addr->zpci); + + VIR_FREE(addr->zpci); +} + + +static int +virDomainZPCIAddressReserveNextUid(virHashTablePtr uids, + virZPCIDeviceAddressPtr zpci) +{ + if (virDomainZPCIAddressAssignUid(uids, zpci) < 0) + return -1; + + if (virDomainZPCIAddressReserveUid(uids, zpci) < 0) + return -1; + + return 0; +} + +static int +virDomainZPCIAddressReserveNextFid(virHashTablePtr fids, + virZPCIDeviceAddressPtr zpci) +{ + if (virDomainZPCIAddressAssignFid(fids, zpci) < 0) + return -1; + + if (virDomainZPCIAddressReserveFid(fids, zpci) < 0) + return -1; + + return 0; +} + static void virDomainPCIAddressSetExtensionFree(virDomainPCIAddressSetPtr addrs) { @@ -44,6 +185,116 @@ virDomainPCIAddressSetExtensionFree(virDomainPCIAddres= sSetPtr addrs) VIR_FREE(addrs->zpciIds); } =20 +static int +virDomainZPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, + virPCIDeviceAddressPtr addr) +{ + if (!addr->zpci) + return 0; + + if (addr->zpci->uid_assigned && + virDomainZPCIAddressReserveUid(addrs->zpciIds->uids, addr->zpci)) + return -1; + + if (addr->zpci->fid_assigned && + virDomainZPCIAddressReserveFid(addrs->zpciIds->fids, addr->zpci)) { + virDomainZPCIAddressReleaseUid(addrs->zpciIds->uids, addr->zpci); + return -1; + } + + return 0; +} + +static int +virDomainZPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, + virZPCIDeviceAddressPtr zpci) +{ + if (!zpci->uid_assigned && + virDomainZPCIAddressReserveNextUid(addrs->zpciIds->uids, zpci)) + return -1; + + if (!zpci->fid_assigned && + virDomainZPCIAddressReserveNextFid(addrs->zpciIds->fids, zpci)) { + virDomainZPCIAddressReleaseUid(addrs->zpciIds->uids, zpci); + return -1; + } + + return 0; +} + + +int +virDomainPCIAddressExtensionReserveAddr(virDomainPCIAddressSetPtr addrs, + virPCIDeviceAddressPtr addr, + virDomainPCIAddressExtensionFlags = extFlags) +{ + if (extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) { + /* Reserve uid/fid to ZPCI device which has defined uid/fid + * in the domain. + */ + if (virDomainZPCIAddressReserveAddr(addrs, addr) < 0) + return -1; + } + + return 0; +} + + +int +virDomainPCIAddressExtensionReserveNextAddr(virDomainPCIAddressSetPtr addr= s, + virPCIDeviceAddressPtr dev, + virDomainPCIAddressExtensionFl= ags extFlags) +{ + if (extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) { + /* Assign and reserve uid/fid to ZPCI device which has not defined uid= /fid + * in the domain. + */ + virZPCIDeviceAddress zpci =3D { 0 }; + + if (dev->zpci) + zpci =3D *dev->zpci; + + if (virDomainZPCIAddressReserveNextAddr(addrs, &zpci) < 0) + return -1; + + if (!addrs->dryRun) { + if (!dev->zpci && VIR_ALLOC(dev->zpci) < 0) + return -1; + *dev->zpci =3D zpci; + } + } + + return 0; +} + +static int +virDomainPCIAddressEnsureExtensionAddr(virDomainPCIAddressSetPtr addrs, + virDomainDeviceInfoPtr dev) +{ + virZPCIDeviceAddressPtr zpci =3D dev->addr.pci.zpci; + + if (zpci && !dev->pciAddressExtFlags) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("zPCI is not suppor= ted.")); + return -1; + } + + if (!zpci) { + return virDomainPCIAddressExtensionReserveNextAddr(addrs, &dev->ad= dr.pci, + dev->pciAddress= ExtFlags); + } else { + if (virDomainZPCIAddressAssignUid(addrs->zpciIds->uids, zpci)) + return -1; + + if (virDomainZPCIAddressAssignFid(addrs->zpciIds->fids, zpci)) + return -1; + + if (virDomainZPCIAddressReserveAddr(addrs, &dev->addr.pci)) + return -1; + } + + return 0; +} + virDomainPCIConnectFlags virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) { @@ -740,12 +991,25 @@ virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetP= tr addrs, ret =3D virDomainPCIAddressReserveNextAddr(addrs, dev, flags, -1); } =20 + if (virDomainPCIAddressEnsureExtensionAddr(addrs, dev) < 0) + goto cleanup; + cleanup: VIR_FREE(addrStr); return ret; } =20 =20 +void +virDomainPCIAddressExtensionReleaseAddr(virDomainPCIAddressSetPtr addrs, + virPCIDeviceAddressPtr addr, + int extFlags) +{ + if ((extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI)) + virDomainZPCIAddressReleaseIds(addrs->zpciIds, addr); +} + + void virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr) diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index f95d56c0a0..86d54e38f2 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -167,6 +167,16 @@ bool virDomainPCIAddressSlotInUse(virDomainPCIAddressS= etPtr addrs, virPCIDeviceAddressPtr addr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 +int virDomainPCIAddressExtensionReserveAddr(virDomainPCIAddressSetPtr addr= s, + virPCIDeviceAddressPtr addr, + virDomainPCIAddressExtensionFl= ags extFlags) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +int virDomainPCIAddressExtensionReserveNextAddr(virDomainPCIAddressSetPtr = addrs, + virPCIDeviceAddressPtr addr, + virDomainPCIAddressExtensionFl= ags extFlags) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + int virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags, @@ -188,6 +198,11 @@ void virDomainPCIAddressReleaseAddr(virDomainPCIAddres= sSetPtr addrs, virPCIDeviceAddressPtr addr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 +void virDomainPCIAddressExtensionReleaseAddr(virDomainPCIAddressSetPtr add= rs, + virPCIDeviceAddressPtr addr, + int extFlags) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + void virDomainPCIAddressSetAllMulti(virDomainDefPtr def) ATTRIBUTE_NONNULL(1); =20 diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7a808331ef..7e184ad99b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -115,6 +115,9 @@ virDomainPCIAddressAsString; virDomainPCIAddressBusIsFullyReserved; virDomainPCIAddressBusSetModel; virDomainPCIAddressEnsureAddr; +virDomainPCIAddressExtensionReleaseAddr; +virDomainPCIAddressExtensionReserveAddr; +virDomainPCIAddressExtensionReserveNextAddr; virDomainPCIAddressReleaseAddr; virDomainPCIAddressReserveAddr; virDomainPCIAddressReserveNextAddr; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index db23b4ef40..bf603496d7 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1390,6 +1390,24 @@ qemuDomainPCIAddressReserveNextAddr(virDomainPCIAddr= essSetPtr addrs, } =20 =20 +static int +qemuDomainAssignPCIAddressExtension(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr device ATTRIBUTE= _UNUSED, + virDomainDeviceInfoPtr info, + void *opaque) +{ + virDomainPCIAddressSetPtr addrs =3D opaque; + virPCIDeviceAddressPtr addr =3D &info->addr.pci; + virDomainPCIAddressExtensionFlags extFlags =3D info->pciAddressExtFlag= s; + + if (info->type =3D=3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + if (virDomainPCIAddressExtensionReserveNextAddr(addrs, addr, extFl= ags) < 0) + return -1; + } + + return 0; +} + static int qemuDomainCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, virDomainDeviceDefPtr device, @@ -1407,7 +1425,12 @@ qemuDomainCollectPCIAddress(virDomainDefPtr def ATTR= IBUTE_UNUSED, * parent, and will have its address collected during the scan * of the parent's device type. */ - return 0; + if (info->type =3D=3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI || + info->type =3D=3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + return virDomainPCIAddressExtensionReserveAddr(addrs, addr, + info->pciAddres= sExtFlags); + else + return 0; } =20 /* If we get to here, the device has a PCI address assigned in the @@ -1478,6 +1501,11 @@ qemuDomainCollectPCIAddress(virDomainDefPtr def ATTR= IBUTE_UNUSED, goto cleanup; } =20 + if (virDomainPCIAddressExtensionReserveAddr(addrs, addr, + info->pciAddressExtFlags) = < 0) { + goto cleanup; + } + ret =3D 0; cleanup: return ret; @@ -2577,6 +2605,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, if (qemuDomainAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup; =20 + if (virDomainDeviceInfoIterate(def, qemuDomainAssignPCIAddressExte= nsion, addrs) < 0) + goto cleanup; + /* Only for *new* domains with pcie-root (and no other * manually specified PCI controllers in the definition): If, * after assigning addresses/reserving slots for all devices, @@ -2671,6 +2702,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, if (qemuDomainAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup; =20 + if (virDomainDeviceInfoIterate(def, qemuDomainAssignPCIAddressExte= nsion, addrs) < 0) + goto cleanup; + /* set multi attribute for devices at function 0 of * any slot that has multiple functions in use */ @@ -3130,8 +3164,11 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm, if (!devstr) devstr =3D info->alias; =20 - if (virDeviceInfoPCIAddressPresent(info)) + if (virDeviceInfoPCIAddressPresent(info)) { virDomainPCIAddressReleaseAddr(priv->pciaddrs, &info->addr.pci); + virDomainPCIAddressExtensionReleaseAddr(priv->pciaddrs, &info->add= r.pci, + info->pciAddressExtFlags); + } =20 if (virDomainUSBAddressRelease(priv->usbaddrs, info) < 0) VIR_WARN("Unable to release USB address on %s", NULLSTR(devstr)); --=20 Yi Min -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list