From nobody Mon Feb 9 02:52:02 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.zoho.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 1495058065931440.76216692554044; Wed, 17 May 2017 14:54:25 -0700 (PDT) Received: from localhost ([::1]:50909 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dB6tk-000090-M8 for importer@patchew.org; Wed, 17 May 2017 17:54:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48336) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dB6lL-0001Ay-2H for qemu-devel@nongnu.org; Wed, 17 May 2017 17:45:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dB6lJ-0005UA-Uq for qemu-devel@nongnu.org; Wed, 17 May 2017 17:45:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34084) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dB6lJ-0005Tv-LI for qemu-devel@nongnu.org; Wed, 17 May 2017 17:45:41 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 89AAF81252; Wed, 17 May 2017 21:45:40 +0000 (UTC) Received: from redhat.com (ovpn-120-251.rdu2.redhat.com [10.10.120.251]) by smtp.corp.redhat.com (Postfix) with SMTP id D0D7717AF0; Wed, 17 May 2017 21:45:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 89AAF81252 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=mst@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 89AAF81252 Date: Thu, 18 May 2017 00:45:35 +0300 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Message-ID: <1495057396-13387-14-git-send-email-mst@redhat.com> References: <1495057396-13387-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1495057396-13387-1-git-send-email-mst@redhat.com> X-Mutt-Fcc: =sent X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 17 May 2017 21:45:40 +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] [PULL 13/13] exec: abstract address_space_do_translate() 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: Peter Maydell , Peter Crosthwaite , Peter Xu , Maxime Coquelin , Paolo Bonzini , Richard Henderson 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 Content-Type: text/plain; charset="utf-8" From: Peter Xu This function is an abstraction helper for address_space_translate() and address_space_get_iotlb_entry(). It does the lookup of address into memory region section, then does proper IOMMU translation if necessary. Refactor the two existing functions to use it. This fixes vhost when IOMMU is disabled by guest. Tested-by: Maxime Coquelin Signed-off-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- exec.c | 103 +++++++++++++++++++++++++++++++++++++++++++------------------= ---- 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/exec.c b/exec.c index eac6085..f942eb2 100644 --- a/exec.c +++ b/exec.c @@ -463,18 +463,20 @@ address_space_translate_internal(AddressSpaceDispatch= *d, hwaddr addr, hwaddr *x } =20 /* Called from RCU critical section */ -IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr, - bool is_write) +static MemoryRegionSection address_space_do_translate(AddressSpace *as, + hwaddr addr, + hwaddr *xlat, + hwaddr *plen, + bool is_write, + bool is_mmio) { - IOMMUTLBEntry iotlb =3D {0}; + IOMMUTLBEntry iotlb; MemoryRegionSection *section; MemoryRegion *mr; =20 for (;;) { AddressSpaceDispatch *d =3D atomic_rcu_read(&as->dispatch); - section =3D address_space_lookup_region(d, addr, false); - addr =3D addr - section->offset_within_address_space - + section->offset_within_region; + section =3D address_space_translate_internal(d, addr, &addr, plen,= is_mmio); mr =3D section->mr; =20 if (!mr->iommu_ops) { @@ -482,55 +484,88 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSp= ace *as, hwaddr addr, } =20 iotlb =3D mr->iommu_ops->translate(mr, addr, is_write); + addr =3D ((iotlb.translated_addr & ~iotlb.addr_mask) + | (addr & iotlb.addr_mask)); + *plen =3D MIN(*plen, (addr | iotlb.addr_mask) - addr + 1); if (!(iotlb.perm & (1 << is_write))) { - iotlb.target_as =3D NULL; - break; + goto translate_fail; } =20 - addr =3D ((iotlb.translated_addr & ~iotlb.addr_mask) - | (addr & iotlb.addr_mask)); as =3D iotlb.target_as; } =20 - return iotlb; + *xlat =3D addr; + + return *section; + +translate_fail: + return (MemoryRegionSection) { .mr =3D &io_mem_unassigned }; } =20 /* Called from RCU critical section */ -MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, - hwaddr *xlat, hwaddr *plen, - bool is_write) +IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr, + bool is_write) { - IOMMUTLBEntry iotlb; - MemoryRegionSection *section; - MemoryRegion *mr; + MemoryRegionSection section; + hwaddr xlat, plen; =20 - for (;;) { - AddressSpaceDispatch *d =3D atomic_rcu_read(&as->dispatch); - section =3D address_space_translate_internal(d, addr, &addr, plen,= true); - mr =3D section->mr; + /* Try to get maximum page mask during translation. */ + plen =3D (hwaddr)-1; =20 - if (!mr->iommu_ops) { - break; - } + /* This can never be MMIO. */ + section =3D address_space_do_translate(as, addr, &xlat, &plen, + is_write, false); =20 - iotlb =3D mr->iommu_ops->translate(mr, addr, is_write); - addr =3D ((iotlb.translated_addr & ~iotlb.addr_mask) - | (addr & iotlb.addr_mask)); - *plen =3D MIN(*plen, (addr | iotlb.addr_mask) - addr + 1); - if (!(iotlb.perm & (1 << is_write))) { - mr =3D &io_mem_unassigned; - break; - } + /* Illegal translation */ + if (section.mr =3D=3D &io_mem_unassigned) { + goto iotlb_fail; + } =20 - as =3D iotlb.target_as; + /* Convert memory region offset into address space offset */ + xlat +=3D section.offset_within_address_space - + section.offset_within_region; + + if (plen =3D=3D (hwaddr)-1) { + /* + * We use default page size here. Logically it only happens + * for identity mappings. + */ + plen =3D TARGET_PAGE_SIZE; } =20 + /* Convert to address mask */ + plen -=3D 1; + + return (IOMMUTLBEntry) { + .target_as =3D section.address_space, + .iova =3D addr & ~plen, + .translated_addr =3D xlat & ~plen, + .addr_mask =3D plen, + /* IOTLBs are for DMAs, and DMA only allows on RAMs. */ + .perm =3D IOMMU_RW, + }; + +iotlb_fail: + return (IOMMUTLBEntry) {0}; +} + +/* Called from RCU critical section */ +MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, + hwaddr *xlat, hwaddr *plen, + bool is_write) +{ + MemoryRegion *mr; + MemoryRegionSection section; + + /* This can be MMIO, so setup MMIO bit. */ + section =3D address_space_do_translate(as, addr, xlat, plen, is_write,= true); + mr =3D section.mr; + if (xen_enabled() && memory_access_is_direct(mr, is_write)) { hwaddr page =3D ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - a= ddr; *plen =3D MIN(page, *plen); } =20 - *xlat =3D addr; return mr; } =20 --=20 MST