From nobody Sun Feb 8 21:29:32 2026 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151816982813241.36432211886586; Fri, 9 Feb 2018 01:50:28 -0800 (PST) Received: from localhost ([::1]:53767 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ek5K1-0006LE-5R for importer@patchew.org; Fri, 09 Feb 2018 04:50:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43888) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ek4wm-0002U4-D5 for qemu-devel@nongnu.org; Fri, 09 Feb 2018 04:26:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ek4wl-0006SX-1w for qemu-devel@nongnu.org; Fri, 09 Feb 2018 04:26:20 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:55824 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ek4wk-0006S2-UA; Fri, 09 Feb 2018 04:26:19 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7EEE2818AB0B; Fri, 9 Feb 2018 09:26:18 +0000 (UTC) Received: from localhost (dhcp-192-222.str.redhat.com [10.33.192.222]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 360652166BAE; Fri, 9 Feb 2018 09:26:18 +0000 (UTC) From: Cornelia Huck To: peter.maydell@linaro.org Date: Fri, 9 Feb 2018 10:25:20 +0100 Message-Id: <20180209092524.31348-26-cohuck@redhat.com> In-Reply-To: <20180209092524.31348-1-cohuck@redhat.com> References: <20180209092524.31348-1-cohuck@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 09 Feb 2018 09:26:18 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 09 Feb 2018 09:26:18 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'cohuck@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PULL 25/29] s390x/pci: fixup global refresh 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: thuth@redhat.com, Yi Min Zhao , david@redhat.com, Cornelia Huck , qemu-devel@nongnu.org, agraf@suse.de, borntraeger@de.ibm.com, qemu-s390x@nongnu.org, rth@twiddle.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Yi Min Zhao The VFIO common code doesn't provide the possibility to modify a previous mapping entry in another way than unmapping and mapping again with new properties. To avoid -EEXIST DMA mapping error, we introduce a GHashTable to store S390IOTLBEntry instances in order to cache the mapped entries. When intercepting rpcit instruction, ignore the identical mapped entries to avoid doing map operations multiple times and do unmap and re-map operations for the case of updating the valid entries. Acked-by: Pierre Morel Signed-off-by: Yi Min Zhao Message-Id: <20180205072258.5968-3-zyimin@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- hw/s390x/s390-pci-bus.c | 24 +++++++++++++++------- hw/s390x/s390-pci-bus.h | 1 + hw/s390x/s390-pci-inst.c | 53 ++++++++++++++++++++++++++++++++++++++++----= ---- 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index e7ef7d28d9..77a50cab36 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -487,7 +487,8 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRe= gion *mr, hwaddr addr, IOMMUAccessFlags flag) { S390PCIIOMMU *iommu =3D container_of(mr, S390PCIIOMMU, iommu_mr); - S390IOTLBEntry entry; + S390IOTLBEntry *entry; + uint64_t iova =3D addr & PAGE_MASK; uint16_t error =3D 0; IOMMUTLBEntry ret =3D { .target_as =3D &address_space_memory, @@ -515,12 +516,17 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemory= Region *mr, hwaddr addr, goto err; } =20 - error =3D s390_guest_io_table_walk(iommu->g_iota, addr, &entry); - - ret.iova =3D entry.iova; - ret.translated_addr =3D entry.translated_addr; - ret.addr_mask =3D entry.len - 1; - ret.perm =3D entry.perm; + entry =3D g_hash_table_lookup(iommu->iotlb, &iova); + if (entry) { + ret.iova =3D entry->iova; + ret.translated_addr =3D entry->translated_addr; + ret.addr_mask =3D entry->len - 1; + ret.perm =3D entry->perm; + } else { + ret.iova =3D iova; + ret.addr_mask =3D ~PAGE_MASK; + ret.perm =3D IOMMU_NONE; + } =20 if (flag !=3D IOMMU_NONE && !(flag & ret.perm)) { error =3D ERR_EVENT_TPROTE; @@ -572,6 +578,8 @@ static S390PCIIOMMU *s390_pci_get_iommu(S390pciState *s= , PCIBus *bus, PCI_FUNC(devfn)); memory_region_init(&iommu->mr, OBJECT(iommu), mr_name, UINT64_MAX); address_space_init(&iommu->as, &iommu->mr, as_name); + iommu->iotlb =3D g_hash_table_new_full(g_int64_hash, g_int64_equal, + NULL, g_free); table->iommu[PCI_SLOT(devfn)] =3D iommu; =20 g_free(mr_name); @@ -661,6 +669,7 @@ void s390_pci_iommu_enable(S390PCIIOMMU *iommu) void s390_pci_iommu_disable(S390PCIIOMMU *iommu) { iommu->enabled =3D false; + g_hash_table_remove_all(iommu->iotlb); memory_region_del_subregion(&iommu->mr, MEMORY_REGION(&iommu->iommu_mr= )); object_unparent(OBJECT(&iommu->iommu_mr)); } @@ -676,6 +685,7 @@ static void s390_pci_iommu_free(S390pciState *s, PCIBus= *bus, int32_t devfn) } =20 table->iommu[PCI_SLOT(devfn)] =3D NULL; + g_hash_table_destroy(iommu->iotlb); address_space_destroy(&iommu->as); object_unparent(OBJECT(&iommu->mr)); object_unparent(OBJECT(iommu)); diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h index 7ed577c806..1f7f9b5814 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -278,6 +278,7 @@ typedef struct S390PCIIOMMU { uint64_t g_iota; uint64_t pba; uint64_t pal; + GHashTable *iotlb; } S390PCIIOMMU; =20 typedef struct S390PCIIOMMUTable { diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 1d33a89351..997a9cc2e9 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -571,6 +571,45 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint= 8_t r2, uintptr_t ra) return 0; } =20 +static void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *ent= ry) +{ + S390IOTLBEntry *cache =3D g_hash_table_lookup(iommu->iotlb, &entry->io= va); + IOMMUTLBEntry notify =3D { + .target_as =3D &address_space_memory, + .iova =3D entry->iova, + .translated_addr =3D entry->translated_addr, + .perm =3D entry->perm, + .addr_mask =3D ~PAGE_MASK, + }; + + if (entry->perm =3D=3D IOMMU_NONE) { + if (!cache) { + return; + } + g_hash_table_remove(iommu->iotlb, &entry->iova); + } else { + if (cache) { + if (cache->perm =3D=3D entry->perm && + cache->translated_addr =3D=3D entry->translated_addr) { + return; + } + + notify.perm =3D IOMMU_NONE; + memory_region_notify_iommu(&iommu->iommu_mr, notify); + notify.perm =3D entry->perm; + } + + cache =3D g_new(S390IOTLBEntry, 1); + cache->iova =3D entry->iova; + cache->translated_addr =3D entry->translated_addr; + cache->len =3D PAGE_SIZE; + cache->perm =3D entry->perm; + g_hash_table_replace(iommu->iotlb, &cache->iova, cache); + } + + memory_region_notify_iommu(&iommu->iommu_mr, notify); +} + int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) { CPUS390XState *env =3D &cpu->env; @@ -580,7 +619,6 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_= t r2, uintptr_t ra) S390PCIIOMMU *iommu; S390IOTLBEntry entry; hwaddr start, end; - IOMMUTLBEntry notify; =20 cpu_synchronize_state(CPU(cpu)); =20 @@ -636,15 +674,14 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint= 8_t r2, uintptr_t ra) if (error) { break; } - notify.target_as =3D &address_space_memory; - notify.iova =3D entry.iova; - notify.translated_addr =3D entry.translated_addr; - notify.addr_mask =3D entry.len - 1; - notify.perm =3D entry.perm; - memory_region_notify_iommu(&iommu->iommu_mr, notify); + start +=3D entry.len; + while (entry.iova < start && entry.iova < end) { + s390_pci_update_iotlb(iommu, &entry); + entry.iova +=3D PAGE_SIZE; + entry.translated_addr +=3D PAGE_SIZE; + } } - err: if (error) { pbdev->state =3D ZPCI_FS_ERROR; --=20 2.13.6