From nobody Wed Oct 29 16:21:37 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1513573570964958.0414583903864; Sun, 17 Dec 2017 21:06:10 -0800 (PST) Received: from localhost ([::1]:56816 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eQncs-0003JJ-VQ for importer@patchew.org; Mon, 18 Dec 2017 00:06:06 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37815) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eQnZS-0000oB-4n for qemu-devel@nongnu.org; Mon, 18 Dec 2017 00:02:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eQnZP-0001bF-1w for qemu-devel@nongnu.org; Mon, 18 Dec 2017 00:02:34 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59292) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eQnZO-0001a3-PG for qemu-devel@nongnu.org; Mon, 18 Dec 2017 00:02:30 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DD30237E72 for ; Mon, 18 Dec 2017 05:02:29 +0000 (UTC) Received: from gimli.home (ovpn-116-49.phx2.redhat.com [10.3.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 91B5978401; Mon, 18 Dec 2017 05:02:29 +0000 (UTC) From: Alex Williamson To: qemu-devel@nongnu.org Date: Sun, 17 Dec 2017 22:02:29 -0700 Message-ID: <20171218050229.13478.65667.stgit@gimli.home> In-Reply-To: <20171218040852.13478.19208.stgit@gimli.home> References: <20171218040852.13478.19208.stgit@gimli.home> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 18 Dec 2017 05:02:29 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC/RFT PATCH 2/5] vfio/pci: Add base BAR MemoryRegion X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eric.auger@redhat.com, alex.williamson@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Add one more layer to our stack of MemoryRegions, this base region allows us to register BARs independently of the vfio region or to extend the size of BARs which do map to a region. This will be useful when we want hypervisor defined BARs or sections of BARs, for purposes such as relocating MSI-X emulation. We therefore call msix_init() based on this new base MemoryRegion, while the quirks, which only modify regions still operate on those sub-MemoryRegions. Signed-off-by: Alex Williamson --- hw/vfio/pci.c | 74 ++++++++++++++++++++++++++++++++++++++++++++---------= ---- hw/vfio/pci.h | 3 ++ 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index c977ee327f94..8f46fdd1d391 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -1440,9 +1440,9 @@ static int vfio_msix_setup(VFIOPCIDevice *vdev, int p= os, Error **errp) vdev->msix->pending =3D g_malloc0(BITS_TO_LONGS(vdev->msix->entries) * sizeof(unsigned long)); ret =3D msix_init(&vdev->pdev, vdev->msix->entries, - vdev->bars[vdev->msix->table_bar].region.mem, + vdev->bars[vdev->msix->table_bar].mr, vdev->msix->table_bar, vdev->msix->table_offset, - vdev->bars[vdev->msix->pba_bar].region.mem, + vdev->bars[vdev->msix->pba_bar].mr, vdev->msix->pba_bar, vdev->msix->pba_offset, pos, &err); if (ret < 0) { @@ -1482,8 +1482,8 @@ static void vfio_teardown_msi(VFIOPCIDevice *vdev) =20 if (vdev->msix) { msix_uninit(&vdev->pdev, - vdev->bars[vdev->msix->table_bar].region.mem, - vdev->bars[vdev->msix->pba_bar].region.mem); + vdev->bars[vdev->msix->table_bar].mr, + vdev->bars[vdev->msix->pba_bar].mr); g_free(vdev->msix->pending); } } @@ -1500,12 +1500,11 @@ static void vfio_mmap_set_enabled(VFIOPCIDevice *vd= ev, bool enabled) } } =20 -static void vfio_bar_setup(VFIOPCIDevice *vdev, int nr) +static void vfio_bar_prepare(VFIOPCIDevice *vdev, int nr) { VFIOBAR *bar =3D &vdev->bars[nr]; =20 uint32_t pci_bar; - uint8_t type; int ret; =20 /* Skip both unimplemented BARs and the upper half of 64bit BARS. */ @@ -1524,23 +1523,52 @@ static void vfio_bar_setup(VFIOPCIDevice *vdev, int= nr) pci_bar =3D le32_to_cpu(pci_bar); bar->ioport =3D (pci_bar & PCI_BASE_ADDRESS_SPACE_IO); bar->mem64 =3D bar->ioport ? 0 : (pci_bar & PCI_BASE_ADDRESS_MEM_TYPE_= 64); - type =3D pci_bar & (bar->ioport ? ~PCI_BASE_ADDRESS_IO_MASK : - ~PCI_BASE_ADDRESS_MEM_MASK); + bar->type =3D pci_bar & (bar->ioport ? ~PCI_BASE_ADDRESS_IO_MASK : + ~PCI_BASE_ADDRESS_MEM_MASK); + bar->size =3D bar->region.size; +} =20 - if (vfio_region_mmap(&bar->region)) { - error_report("Failed to mmap %s BAR %d. Performance may be slow", - vdev->vbasedev.name, nr); +static void vfio_bars_prepare(VFIOPCIDevice *vdev) +{ + int i; + + for (i =3D 0; i < PCI_ROM_SLOT; i++) { + vfio_bar_prepare(vdev, i); } +} =20 - pci_register_bar(&vdev->pdev, nr, type, bar->region.mem); +static void vfio_bar_register(VFIOPCIDevice *vdev, int nr) +{ + VFIOBAR *bar =3D &vdev->bars[nr]; + char *name; + + if (!bar->size) { + return; + } + + bar->mr =3D g_new0(MemoryRegion, 1); + name =3D g_strdup_printf("%s base BAR %d", vdev->vbasedev.name, nr); + memory_region_init_io(bar->mr, OBJECT(vdev), NULL, NULL, name, bar->si= ze); + g_free(name); + + if (bar->region.size) { + memory_region_add_subregion(bar->mr, 0, bar->region.mem); + + if (vfio_region_mmap(&bar->region)) { + error_report("Failed to mmap %s BAR %d. Performance may be slo= w", + vdev->vbasedev.name, nr); + } + } + + pci_register_bar(&vdev->pdev, nr, bar->type, bar->mr); } =20 -static void vfio_bars_setup(VFIOPCIDevice *vdev) +static void vfio_bars_register(VFIOPCIDevice *vdev) { int i; =20 for (i =3D 0; i < PCI_ROM_SLOT; i++) { - vfio_bar_setup(vdev, i); + vfio_bar_register(vdev, i); } } =20 @@ -1549,8 +1577,13 @@ static void vfio_bars_exit(VFIOPCIDevice *vdev) int i; =20 for (i =3D 0; i < PCI_ROM_SLOT; i++) { + VFIOBAR *bar =3D &vdev->bars[i]; + vfio_bar_quirk_exit(vdev, i); - vfio_region_exit(&vdev->bars[i].region); + vfio_region_exit(&bar->region); + if (bar->region.size) { + memory_region_del_subregion(bar->mr, bar->region.mem); + } } =20 if (vdev->vga) { @@ -1564,8 +1597,14 @@ static void vfio_bars_finalize(VFIOPCIDevice *vdev) int i; =20 for (i =3D 0; i < PCI_ROM_SLOT; i++) { + VFIOBAR *bar =3D &vdev->bars[i]; + vfio_bar_quirk_finalize(vdev, i); - vfio_region_finalize(&vdev->bars[i].region); + vfio_region_finalize(&bar->region); + if (bar->size) { + object_unparent(OBJECT(bar->mr)); + g_free(bar->mr); + } } =20 if (vdev->vga) { @@ -2810,7 +2849,8 @@ static void vfio_realize(PCIDevice *pdev, Error **err= p) goto error; } =20 - vfio_bars_setup(vdev); + vfio_bars_prepare(vdev); + vfio_bars_register(vdev); =20 ret =3D vfio_add_capabilities(vdev, errp); if (ret) { diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index 3d753222ca4c..dcdb1a806769 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -33,6 +33,9 @@ typedef struct VFIOQuirk { =20 typedef struct VFIOBAR { VFIORegion region; + MemoryRegion *mr; + size_t size; + uint8_t type; bool ioport; bool mem64; QLIST_HEAD(, VFIOQuirk) quirks;