From nobody Sun Feb 8 14:12:34 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) client-ip=205.139.110.61; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1590009158; cv=none; d=zohomail.com; s=zohoarc; b=FK2Pi8HFIFNs+eoXcW0E37XHovGEAsVWeRw5+QXy0ecaSM/Vb8CpvWS/VdzqV7/fzZgfLjNMXEIAFl6LvkuyfM3LUIeNvvqRgLSPv+amNCSxXPpc763nOpCi++y4VBz7iyen4F1r35Krh022HKhttMoX6Rc0RdpJ/+XUGH6rTUE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1590009158; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=rqmCTOhMcmZw6KYqwvaKr4Cz6BVm264h5D90siwqZTY=; b=YB36ssWj2sFOvqmtuPrwyqjQ9QDb01g1zA06k7mri7SFJlf/s2k1gwAVHMIafcz6GNZNVEaUkdPDR+uNJ1MN0jtqMjORZWXfaqo3zKpWIcqMyikSXe0ngUR0pvvoDtMKI+uy6AFmdP9WDc0DlY/KS4DPWgZjKg0eXTAeVKmnlrk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) by mx.zohomail.com with SMTPS id 159000915871739.8544305600293; Wed, 20 May 2020 14:12:38 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-410-zXeFeNxVNciFTkOZYmjAeA-1; Wed, 20 May 2020 17:12:33 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D0DC21855A1F; Wed, 20 May 2020 21:12:27 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AE2C25D9CD; Wed, 20 May 2020 21:12:27 +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 81AF24EE4A; Wed, 20 May 2020 21:12:27 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 04KLCAlZ002004 for ; Wed, 20 May 2020 17:12:10 -0400 Received: by smtp.corp.redhat.com (Postfix) id 5AB2C2029F61; Wed, 20 May 2020 21:12:10 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5436C202696C for ; Wed, 20 May 2020 21:12:08 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-2.mimecast.com [207.211.31.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 333C9811E7A for ; Wed, 20 May 2020 21:12:08 +0000 (UTC) Received: from mail-qk1-f195.google.com (mail-qk1-f195.google.com [209.85.222.195]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-413-y3gm5nj4P4KbjEYB_UC1aA-1; Wed, 20 May 2020 17:12:06 -0400 Received: by mail-qk1-f195.google.com with SMTP id n14so5134461qke.8 for ; Wed, 20 May 2020 14:12:05 -0700 (PDT) Received: from rekt.ibmuc.com ([2804:431:c7c7:fbf2:bc5e:c314:af31:7070]) by smtp.gmail.com with ESMTPSA id z14sm2992031qki.83.2020.05.20.14.12.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2020 14:12:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1590009157; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=rqmCTOhMcmZw6KYqwvaKr4Cz6BVm264h5D90siwqZTY=; b=H4zkeimGSGowW3BVccS94fz8cF94Z+5L60ilTrZqHP2askedw2GNc8GgMSSCrvLod0n2VR gjNJIymViCCzJmtd50H77icqYbxvwMC7qK3wy+hHgNksy+1aEz0de5nxKCDPVbA8ndg91S 33fLUgfZLU4g3elAtJWPqDUDOxDE0Fw= X-MC-Unique: zXeFeNxVNciFTkOZYmjAeA-1 X-MC-Unique: y3gm5nj4P4KbjEYB_UC1aA-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rqmCTOhMcmZw6KYqwvaKr4Cz6BVm264h5D90siwqZTY=; b=DTNRDYgwXYltzS+GG/n4fuMQhlNr6DUNhQbVMU/3Ipl7/xpt77JSD2/XmhkPOqoyay L3UAvgrhTPyVwo9ZeR5NDaYyFiTLFfITH8NWvfiUGBaPlC+xGJ+AmIypeFcgDq4lKp1M sWpU7z2sYcEUvBjG85CJKLiJSim6up/RP6Z289Za7HBWxs5B1CKtp5TbnmCzpUU4jKYr zgpPgPiXXYu5V5h32A7IAl6bMj6QacqVLIgdyYTQ3j1q/ykVIO0otBUsVa3jke6imoYM PHajVbXfZSonw4MYC4JLuWR7iT2q/luI15EUlDt7opDhkrul0lgM1xcnQtmFV15X2mzn cdkQ== X-Gm-Message-State: AOAM533d9XGiJy79YM/qqSxg4fhoNftbckWZrQnDFJF6oVWnO+HztwU4 4AHm44vbzemAdP4RwcjyzfLrK7Jd X-Google-Smtp-Source: ABdhPJy1Jr/GvjhCBH+SmQx7AGc8fy4f0vrkmNG25kBmu1jry8gX7UliGJvbAajdDQW8APTYte9Iqg== X-Received: by 2002:a37:57c5:: with SMTP id l188mr3160367qkb.273.1590009124946; Wed, 20 May 2020 14:12:04 -0700 (PDT) From: Daniel Henrique Barboza To: libvir-list@redhat.com Subject: [PATCH v3 01/21] qemu: address: Separate the slots into multiple aggregates Date: Wed, 20 May 2020 18:11:23 -0300 Message-Id: <20200520211143.2980117-2-danielhb413@gmail.com> In-Reply-To: <20200520211143.2980117-1-danielhb413@gmail.com> References: <20200520211143.2980117-1-danielhb413@gmail.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-loop: libvir-list@redhat.com Cc: Daniel Henrique Barboza , sbhat@linux.ibm.com 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: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" From: Shivaprasad G Bhat Today's aggregate flag with the slot being true for pcie-root-ports is not enough as there will more number of aggregates depending on the number of Multifunction PCI cards assigned to the domain. The aggregate is changed to unsigned int. Zero means Not Applicable, 1 is reserved for the pcie-root-ports and >=3D 2 for the the PCI Multifunction cards(coming..). Signed-off-by: Shivaprasad G Bhat Signed-off-by: Daniel Henrique Barboza --- src/conf/device_conf.h | 1 + src/conf/domain_addr.c | 46 +++++++++++++------ src/conf/domain_addr.h | 38 +++++++-------- src/qemu/qemu_domain_address.c | 84 ++++++++++++++++++++++++++++------ src/qemu/qemu_domain_address.h | 9 ++++ 5 files changed, 128 insertions(+), 50 deletions(-) diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index d7395f2201..cc1707c1d1 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -169,6 +169,7 @@ struct _virDomainDeviceInfo { */ int pciAddrExtFlags; /* enum virDomainPCIAddressExtensionFlags */ char *loadparm; + unsigned int aggregateSlotIdx; /* Used when the aggregate flag is set = */ =20 /* PCI devices will only be automatically placed on a PCI bus * that shares the same isolation group */ diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 8623e79daf..5c8fc62725 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -297,7 +297,7 @@ virDomainPCIControllerModelToConnectType(virDomainContr= ollerModelPCI model) return VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE; =20 case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT | VIR_PCI_CONNECT_AGGRE= GATE_SLOT; + return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT; =20 case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: return VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT; @@ -843,6 +843,7 @@ virDomainPCIAddressReserveAddrInternal(virDomainPCIAddr= essSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags, unsigned int isolationGroup, + unsigned int aggregateSlotIdx, bool fromConfig) { g_autofree char *addrStr =3D NULL; @@ -874,9 +875,14 @@ virDomainPCIAddressReserveAddrInternal(virDomainPCIAdd= ressSetPtr addrs, * the device it's being reserved for can aggregate multiples on a * slot, set the slot's aggregate flag. */ - if (!bus->slot[addr->slot].functions && - flags & VIR_PCI_CONNECT_AGGREGATE_SLOT) { - bus->slot[addr->slot].aggregate =3D true; + if (!bus->slot[addr->slot].functions && aggregateSlotIdx > 0) { + bus->slot[addr->slot].aggregateSlotIdx =3D aggregateSlotIdx; + } else if (bus->slot[addr->slot].aggregateSlotIdx !=3D + aggregateSlotIdx && fromConfig) { + bus->slot[addr->slot].aggregateSlotIdx =3D 0; + VIR_DEBUG("PCI functions of %.4x:%.2x is aggregated to slot %u" + "because of user assigned address %s", + addr->domain, addr->bus, aggregateSlotIdx, addrStr); } =20 if (virDomainPCIAddressBusIsEmpty(bus) && !bus->isolationGroupLocked) { @@ -901,8 +907,8 @@ virDomainPCIAddressReserveAddrInternal(virDomainPCIAddr= essSetPtr addrs, =20 /* mark the requested function as reserved */ bus->slot[addr->slot].functions |=3D (1 << addr->function); - VIR_DEBUG("Reserving PCI address %s (aggregate=3D'%s')", addrStr, - bus->slot[addr->slot].aggregate ? "true" : "false"); + VIR_DEBUG("Reserving PCI address %s (aggregateSlotIdx=3D'%d')", + addrStr, bus->slot[addr->slot].aggregateSlotIdx); =20 return 0; } @@ -912,10 +918,12 @@ int virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags, - unsigned int isolationGroup) + unsigned int isolationGroup, + unsigned int aggregateSlotIdx) { return virDomainPCIAddressReserveAddrInternal(addrs, addr, flags, - isolationGroup, true); + isolationGroup, + aggregateSlotIdx, true); } =20 int @@ -956,6 +964,7 @@ virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr= addrs, =20 if (virDomainPCIAddressReserveAddrInternal(addrs, &dev->addr.pci, flags, dev->isolationGr= oup, + dev->aggregateSlotIdx, true) < 0) { return -1; } @@ -1112,6 +1121,7 @@ virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr = addrs) static int virDomainPCIAddressFindUnusedFunctionOnBus(virDomainPCIAddressBusPtr bus, virPCIDeviceAddressPtr searchAd= dr, + unsigned int aggregateSlotIdx, int function, virDomainPCIConnectFlags flags, bool *found) @@ -1134,8 +1144,8 @@ virDomainPCIAddressFindUnusedFunctionOnBus(virDomainP= CIAddressBusPtr bus, break; } =20 - if (flags & VIR_PCI_CONNECT_AGGREGATE_SLOT && - bus->slot[searchAddr->slot].aggregate) { + if (bus->slot[searchAddr->slot].aggregateSlotIdx > 0 && + bus->slot[searchAddr->slot].aggregateSlotIdx =3D=3D aggreg= ateSlotIdx) { /* slot and device are okay with aggregating devices */ if ((bus->slot[searchAddr->slot].functions & (1 << searchAddr->function)) =3D=3D 0) { @@ -1176,6 +1186,7 @@ virDomainPCIAddressGetNextAddr(virDomainPCIAddressSet= Ptr addrs, virPCIDeviceAddressPtr next_addr, virDomainPCIConnectFlags flags, unsigned int isolationGroup, + unsigned int aggregateSlotIdx, int function) { virPCIDeviceAddress a =3D { 0 }; @@ -1204,7 +1215,9 @@ virDomainPCIAddressGetNextAddr(virDomainPCIAddressSet= Ptr addrs, =20 a.slot =3D bus->minSlot; =20 - if (virDomainPCIAddressFindUnusedFunctionOnBus(bus, &a, function, + if (virDomainPCIAddressFindUnusedFunctionOnBus(bus, &a, + aggregateSlotIdx, + function, flags, &found) < 0)= { return -1; } @@ -1228,7 +1241,9 @@ virDomainPCIAddressGetNextAddr(virDomainPCIAddressSet= Ptr addrs, =20 a.slot =3D bus->minSlot; =20 - if (virDomainPCIAddressFindUnusedFunctionOnBus(bus, &a, function, + if (virDomainPCIAddressFindUnusedFunctionOnBus(bus, &a, + aggregateSlotIdx, + function, flags, &found) < 0)= { return -1; } @@ -1286,12 +1301,13 @@ virDomainPCIAddressReserveNextAddr(virDomainPCIAddr= essSetPtr addrs, { virPCIDeviceAddress addr; =20 - if (virDomainPCIAddressGetNextAddr(addrs, &addr, flags, - dev->isolationGroup, function) < 0) + if (virDomainPCIAddressGetNextAddr(addrs, &addr, flags, dev->isolation= Group, + dev->aggregateSlotIdx, function) < = 0) return -1; =20 if (virDomainPCIAddressReserveAddrInternal(addrs, &addr, flags, - dev->isolationGroup, false)= < 0) + dev->isolationGroup, + dev->aggregateSlotIdx, fals= e) < 0) return -1; =20 addr.extFlags =3D dev->addr.pci.extFlags; diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index c1363c1490..ddcff36e51 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -35,24 +35,19 @@ typedef enum { VIR_PCI_CONNECT_AUTOASSIGN =3D 1 << 0, /* okay to autoassign a device = to this controller */ VIR_PCI_CONNECT_HOTPLUGGABLE =3D 1 << 1, /* is hotplug needed/supporte= d */ =20 - /* set for devices that can share a single slot in auto-assignment - * (by assigning one device to each of the 8 functions on the slot) - */ - VIR_PCI_CONNECT_AGGREGATE_SLOT =3D 1 << 2, - /* kinds of devices as a bitmap so they can be combined (some PCI * controllers permit connecting multiple types of devices) */ - VIR_PCI_CONNECT_TYPE_PCI_DEVICE =3D 1 << 3, - VIR_PCI_CONNECT_TYPE_PCIE_DEVICE =3D 1 << 4, - VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT =3D 1 << 5, - VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT =3D 1 << 6, - VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT =3D 1 << 7, - VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE =3D 1 << 8, - VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS =3D 1 << 9, - VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS =3D 1 << 10, - VIR_PCI_CONNECT_TYPE_PCI_BRIDGE =3D 1 << 11, - VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE =3D 1 << 12, + VIR_PCI_CONNECT_TYPE_PCI_DEVICE =3D 1 << 2, + VIR_PCI_CONNECT_TYPE_PCIE_DEVICE =3D 1 << 3, + VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT =3D 1 << 4, + VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT =3D 1 << 5, + VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT =3D 1 << 6, + VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE =3D 1 << 7, + VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS =3D 1 << 8, + VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS =3D 1 << 9, + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE =3D 1 << 10, + VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE =3D 1 << 11, } virDomainPCIConnectFlags; =20 /* a combination of all bits that describe the type of connections @@ -86,12 +81,12 @@ typedef struct { */ uint8_t functions; =20 - /* aggregate is true if this slot has only devices with - * VIR_PCI_CONNECT_AGGREGATE assigned to its functions (meaning - * that other devices with the same flags could also be - * auto-assigned to the other functions) + /* aggregate is greater than zero if this slot has only devices with + * VIR_PCI_CONNECT_AGGREGATE assigned to its functions and + * that other devices with the same aggregateSlotIdx could also be + * auto-assigned to the other functions on this slot) */ - bool aggregate; + unsigned int aggregateSlotIdx; } virDomainPCIAddressSlot; =20 typedef struct { @@ -170,7 +165,8 @@ int virDomainPCIAddressExtensionReserveNextAddr(virDoma= inPCIAddressSetPtr addrs, int virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags, - unsigned int isolationGroup) + unsigned int isolationGroup, + unsigned int agregateSlotIdx) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 int virDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 07431343ed..f86c85eaa9 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -24,6 +24,7 @@ #include "qemu_domain_address.h" #include "qemu_domain.h" #include "viralloc.h" +#include "virhostdev.h" #include "virerror.h" #include "virlog.h" =20 @@ -1419,6 +1420,54 @@ qemuDomainSetupIsolationGroups(virDomainDefPtr def) } =20 =20 +void +qemuDomainSetDeviceSlotAggregateIdx(virDomainDefPtr def G_GNUC_UNUSED, + virDomainDeviceDefPtr dev) +{ + virDomainDeviceInfoPtr info =3D virDomainDeviceGetInfo(dev); + + if (!info) + return; + + info->aggregateSlotIdx =3D 0; + + if (dev->type =3D=3D VIR_DOMAIN_DEVICE_CONTROLLER) { + virDomainControllerDefPtr cont =3D dev->data.controller; + if (cont->type =3D=3D VIR_DOMAIN_CONTROLLER_TYPE_PCI && + cont->model =3D=3D VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT)= { + info->aggregateSlotIdx =3D 1; + } + } + + return; +} + + +static int +qemuDomainFillDeviceSlotAggregationIter(virDomainDefPtr def, + virDomainDeviceDefPtr dev, + virDomainDeviceInfoPtr info G_GNUC= _UNUSED, + void *opaque G_GNUC_UNUSED) +{ + qemuDomainSetDeviceSlotAggregateIdx(def, dev); + + return 0; +} + + +static int +qemuDomainSetupSlotAggregation(virDomainDefPtr def) +{ + if (virDomainDeviceInfoIterate(def, + qemuDomainFillDeviceSlotAggregationIter, + NULL) < 0) { + return -1; + } + + return 0; +} + + /** * qemuDomainFillDevicePCIConnectFlags: * @@ -1590,7 +1639,8 @@ qemuDomainCollectPCIAddress(virDomainDefPtr def G_GNU= C_UNUSED, =20 if (virDomainPCIAddressReserveAddr(addrs, addr, info->pciConnectFlags, - info->isolationGroup) < 0) { + info->isolationGroup, + info->aggregateSlotIdx) < 0) { return -1; } =20 @@ -1787,7 +1837,7 @@ qemuDomainValidateDevicePCISlotsPIIX3(virDomainDefPtr= def, continue; } if (addrs->nbuses && - virDomainPCIAddressReserveAddr(addrs, &cont->info.addr.pci, fl= ags, 0) < 0) + virDomainPCIAddressReserveAddr(addrs, &cont->info.addr.pci, fl= ags, 0, 0) < 0) return -1; } =20 @@ -1796,11 +1846,11 @@ qemuDomainValidateDevicePCISlotsPIIX3(virDomainDefP= tr def, memset(&tmp_addr, 0, sizeof(tmp_addr)); tmp_addr.slot =3D 1; /* ISA Bridge at 00:01.0 */ - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0, 0) = < 0) return -1; /* Bridge at 00:01.3 */ tmp_addr.function =3D 3; - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0, 0) = < 0) return -1; } =20 @@ -1841,7 +1891,7 @@ qemuDomainValidateDevicePCISlotsPIIX3(virDomainDefPtr= def, return -1; } } else { - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags= , 0) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags= , 0, 0) < 0) return -1; primaryVideo->info.addr.pci =3D tmp_addr; primaryVideo->info.type =3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE= _PCI; @@ -1864,7 +1914,7 @@ qemuDomainValidateDevicePCISlotsPIIX3(virDomainDefPtr= def, VIR_DEBUG("PCI address 0:0:2.0 in use, future addition of a vi= deo" " device will not be possible without manual" " intervention"); - } else if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,= 0) < 0) { + } else if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,= 0, 0) < 0) { return -1; } } @@ -1934,7 +1984,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr d= ef, assign =3D true; } if (assign) { - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, f= lags, 0) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, f= lags, 0, 0) < 0) return -1; =20 cont->info.type =3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; @@ -1957,7 +2007,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr d= ef, memset(&tmp_addr, 0, sizeof(tmp_addr)); tmp_addr.slot =3D 0x1E; if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, f= lags, 0) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, f= lags, 0, 0) < 0) return -1; =20 cont->info.type =3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; @@ -1981,12 +2031,12 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr= def, tmp_addr.slot =3D 0x1F; tmp_addr.function =3D 0; tmp_addr.multi =3D VIR_TRISTATE_SWITCH_ON; - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0, 0) = < 0) return -1; =20 tmp_addr.function =3D 3; tmp_addr.multi =3D VIR_TRISTATE_SWITCH_ABSENT; - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0, 0) = < 0) return -1; } =20 @@ -2023,7 +2073,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr d= ef, return -1; } } else { - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags= , 0) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags= , 0, 0) < 0) return -1; primaryVideo->info.type =3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE= _PCI; primaryVideo->info.addr.pci =3D tmp_addr; @@ -2049,7 +2099,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr d= ef, " device will not be possible without manual" " intervention"); virResetLastError(); - } else if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,= 0) < 0) { + } else if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,= 0, 0) < 0) { return -1; } } @@ -2070,7 +2120,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr d= ef, !virDeviceInfoPCIAddressIsWanted(&sound->info)) { continue; } - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0)= < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0,= 0) < 0) return -1; =20 sound->info.type =3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; @@ -2272,7 +2322,8 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, /* Reserve this function on the slot we found */ if (virDomainPCIAddressReserveAddr(addrs, &addr, cont->info.pciConnectFl= ags, - cont->info.isolationGro= up) < 0) { + cont->info.isolationGro= up, + cont->info.aggregateSlo= tIdx) < 0) { return -1; } =20 @@ -2646,6 +2697,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, if (qemuDomainSetupIsolationGroups(def) < 0) goto cleanup; =20 + if (qemuDomainSetupSlotAggregation(def) < 0) + goto cleanup; + if (nbuses > 0) { /* 1st pass to figure out how many PCI bridges we need */ if (!(addrs =3D qemuDomainPCIAddressSetCreate(def, qemuCaps, nbuse= s, true))) @@ -2766,6 +2820,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, dev.data.controller =3D def->controllers[contIndex]; /* set connect flags so it will be properly addressed */ qemuDomainFillDevicePCIConnectFlags(def, &dev, qemuCaps, drive= r); + qemuDomainSetDeviceSlotAggregateIdx(def, &dev); =20 /* Reserve an address for the controller. pci-root and pcie-ro= ot * controllers don't plug into any other PCI controller, hence @@ -3239,6 +3294,7 @@ qemuDomainEnsurePCIAddress(virDomainObjPtr obj, return 0; =20 qemuDomainFillDevicePCIConnectFlags(obj->def, dev, priv->qemuCaps, dri= ver); + qemuDomainSetDeviceSlotAggregateIdx(obj->def, dev); =20 qemuDomainFillDevicePCIExtensionFlags(dev, info, priv->qemuCaps); =20 diff --git a/src/qemu/qemu_domain_address.h b/src/qemu/qemu_domain_address.h index 7ef3308246..198f813595 100644 --- a/src/qemu/qemu_domain_address.h +++ b/src/qemu/qemu_domain_address.h @@ -53,6 +53,15 @@ void qemuDomainFillDeviceIsolationGroup(virDomainDefPtr = def, virDomainDeviceDefPtr dev) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 +void +qemuDomainSetDeviceSlotAggregateIdx(virDomainDefPtr def, + virDomainDeviceDefPtr dev); + +int +qemuDomainDefDeviceFindSlotAggregateIdx(virDomainDefPtr def, + virDomainDeviceDefPtr dev); + + void qemuDomainReleaseDeviceAddress(virDomainObjPtr vm, virDomainDeviceInfoPtr info); =20 --=20 2.26.2