From nobody Thu Oct 30 15:17:04 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; 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 1526548234081480.6847608426076; Thu, 17 May 2018 02:10:34 -0700 (PDT) Received: from localhost ([::1]:44050 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fJEvh-0000aA-AE for importer@patchew.org; Thu, 17 May 2018 05:10:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59320) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fJElh-0001AQ-6q for qemu-devel@nongnu.org; Thu, 17 May 2018 05:00:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fJElb-0006yD-3v for qemu-devel@nongnu.org; Thu, 17 May 2018 05:00:13 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:51838 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 1fJEla-0006xt-PK for qemu-devel@nongnu.org; Thu, 17 May 2018 05:00:07 -0400 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 D394640200A3; Thu, 17 May 2018 09:00:05 +0000 (UTC) Received: from xz-mi.redhat.com (ovpn-12-109.pek2.redhat.com [10.72.12.109]) by smtp.corp.redhat.com (Postfix) with ESMTP id EEB552166BC7; Thu, 17 May 2018 09:00:02 +0000 (UTC) From: Peter Xu To: qemu-devel@nongnu.org Date: Thu, 17 May 2018 16:59:25 +0800 Message-Id: <20180517085927.24925-11-peterx@redhat.com> In-Reply-To: <20180517085927.24925-1-peterx@redhat.com> References: <20180517085927.24925-1-peterx@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.6]); Thu, 17 May 2018 09:00:05 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Thu, 17 May 2018 09:00:05 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'peterx@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] [PATCH v3 10/12] intel-iommu: simplify page walk logic 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: Tian Kevin , "Michael S . Tsirkin" , Jason Wang , peterx@redhat.com, Alex Williamson , Jintack Lim 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" Let's move the notify_unmap check into the new vtd_page_walk_one() function so that we can greatly simplify the vtd_page_walk_level() logic. No functional change at all. Signed-off-by: Peter Xu --- hw/i386/intel_iommu.c | 66 ++++++++++++++++++++----------------------- hw/i386/trace-events | 1 - 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 5a5175a4ed..272e49ff66 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -779,6 +779,11 @@ static int vtd_page_walk_one(IOMMUTLBEntry *entry, vtd= _page_walk_info *info) }; DMAMap *mapped =3D iova_tree_find(as->iova_tree, &target); =20 + if (entry->perm =3D=3D IOMMU_NONE && !info->notify_unmap) { + trace_vtd_page_walk_one_skip_unmap(entry->iova, entry->addr_mask); + return 0; + } + assert(hook_fn); =20 /* Update local IOVA mapped ranges */ @@ -894,45 +899,34 @@ static int vtd_page_walk_level(dma_addr_t addr, uint6= 4_t start, */ entry_valid =3D read_cur | write_cur; =20 - entry.target_as =3D &address_space_memory; - entry.iova =3D iova & subpage_mask; - entry.perm =3D IOMMU_ACCESS_FLAG(read_cur, write_cur); - entry.addr_mask =3D ~subpage_mask; - - if (vtd_is_last_slpte(slpte, level)) { - /* NOTE: this is only meaningful if entry_valid =3D=3D true */ - entry.translated_addr =3D vtd_get_slpte_addr(slpte, info->aw); - if (!entry_valid && !info->notify_unmap) { - trace_vtd_page_walk_skip_perm(iova, iova_next); - goto next; - } - ret =3D vtd_page_walk_one(&entry, info); - if (ret < 0) { - return ret; - } - } else { - if (!entry_valid) { - if (info->notify_unmap) { - /* - * The whole entry is invalid; unmap it all. - * Translated address is meaningless, zero it. - */ - entry.translated_addr =3D 0x0; - ret =3D vtd_page_walk_one(&entry, info); - if (ret < 0) { - return ret; - } - } else { - trace_vtd_page_walk_skip_perm(iova, iova_next); - } - goto next; - } + if (!vtd_is_last_slpte(slpte, level) && entry_valid) { + /* + * This is a valid PDE (or even bigger than PDE). We need + * to walk one further level. + */ ret =3D vtd_page_walk_level(vtd_get_slpte_addr(slpte, info->aw= ), iova, MIN(iova_next, end), level - 1, read_cur, write_cur, info); - if (ret < 0) { - return ret; - } + } else { + /* + * This means we are either: + * + * (1) the real page entry (either 4K page, or huge page) + * (2) the whole range is invalid + * + * In either case, we send an IOTLB notification down. + */ + entry.target_as =3D &address_space_memory; + entry.iova =3D iova & subpage_mask; + entry.perm =3D IOMMU_ACCESS_FLAG(read_cur, write_cur); + entry.addr_mask =3D ~subpage_mask; + /* NOTE: this is only meaningful if entry_valid =3D=3D true */ + entry.translated_addr =3D vtd_get_slpte_addr(slpte, info->aw); + ret =3D vtd_page_walk_one(&entry, info); + } + + if (ret < 0) { + return ret; } =20 next: diff --git a/hw/i386/trace-events b/hw/i386/trace-events index d8194b80e3..e14d06ec83 100644 --- a/hw/i386/trace-events +++ b/hw/i386/trace-events @@ -43,7 +43,6 @@ vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_= t gpa, uint64_t mask, i vtd_page_walk_one_skip_map(uint64_t iova, uint64_t mask, uint64_t translat= ed) "iova 0x%"PRIx64" mask 0x%"PRIx64" translated 0x%"PRIx64 vtd_page_walk_one_skip_unmap(uint64_t iova, uint64_t mask) "iova 0x%"PRIx6= 4" mask 0x%"PRIx64 vtd_page_walk_skip_read(uint64_t iova, uint64_t next) "Page walk skip iova= 0x%"PRIx64" - 0x%"PRIx64" due to unable to read" -vtd_page_walk_skip_perm(uint64_t iova, uint64_t next) "Page walk skip iova= 0x%"PRIx64" - 0x%"PRIx64" due to perm empty" vtd_page_walk_skip_reserve(uint64_t iova, uint64_t next) "Page walk skip i= ova 0x%"PRIx64" - 0x%"PRIx64" due to rsrv set" vtd_switch_address_space(uint8_t bus, uint8_t slot, uint8_t fn, bool on) "= Device %02x:%02x.%x switching address space (iommu enabled=3D%d)" vtd_as_unmap_whole(uint8_t bus, uint8_t slot, uint8_t fn, uint64_t iova, u= int64_t size) "Device %02x:%02x.%x start 0x%"PRIx64" size 0x%"PRIx64 --=20 2.17.0