From nobody Wed Oct 29 09:14:49 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 1524632064738822.3547329714368; Tue, 24 Apr 2018 21:54:24 -0700 (PDT) Received: from localhost ([::1]:33834 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBCRe-0005LA-Pt for importer@patchew.org; Wed, 25 Apr 2018 00:54:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59002) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBCPX-0004Bv-HT for qemu-devel@nongnu.org; Wed, 25 Apr 2018 00:52:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fBCPW-0007LS-HE for qemu-devel@nongnu.org; Wed, 25 Apr 2018 00:52:07 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:59396 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 1fBCPW-0007LA-C3 for qemu-devel@nongnu.org; Wed, 25 Apr 2018 00:52:06 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E5358406C756; Wed, 25 Apr 2018 04:52:05 +0000 (UTC) Received: from xz-mi.redhat.com (ovpn-12-55.pek2.redhat.com [10.72.12.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4737C7C43; Wed, 25 Apr 2018 04:52:02 +0000 (UTC) From: Peter Xu To: qemu-devel@nongnu.org Date: Wed, 25 Apr 2018 12:51:24 +0800 Message-Id: <20180425045129.17449-6-peterx@redhat.com> In-Reply-To: <20180425045129.17449-1-peterx@redhat.com> References: <20180425045129.17449-1-peterx@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Wed, 25 Apr 2018 04:52:05 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Wed, 25 Apr 2018 04:52:05 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.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 05/10] intel-iommu: introduce vtd_page_walk_info 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: Jason Wang , Alex Williamson , Jintack Lim , peterx@redhat.com, "Michael S . Tsirkin" 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" During the recursive page walking of IOVA page tables, some stack variables are constant variables and never changed during the whole page walking procedure. Isolate them into a struct so that we don't need to pass those contants down the stack every time and multiple times. Signed-off-by: Peter Xu --- hw/i386/intel_iommu.c | 56 ++++++++++++++++++++++++++++++++++-------------= ---- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 1c252414a9..42f607676c 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -750,9 +750,27 @@ static int vtd_iova_to_slpte(VTDContextEntry *ce, uint= 64_t iova, bool is_write, =20 typedef int (*vtd_page_walk_hook)(IOMMUTLBEntry *entry, void *private); =20 +/** + * Constant information used during page walking + * + * @hook_fn: hook func to be called when detected page + * @private: private data to be passed into hook func + * @notify_unmap: whether we should notify invalid entries + * @aw: maximum address width + */ +typedef struct { + vtd_page_walk_hook hook_fn; + void *private; + bool notify_unmap; + uint8_t aw; +} vtd_page_walk_info; + static int vtd_page_walk_one(IOMMUTLBEntry *entry, int level, - vtd_page_walk_hook hook_fn, void *private) + vtd_page_walk_info *info) { + vtd_page_walk_hook hook_fn =3D info->hook_fn; + void *private =3D info->private; + assert(hook_fn); trace_vtd_page_walk_one(level, entry->iova, entry->translated_addr, entry->addr_mask, entry->perm); @@ -765,17 +783,13 @@ static int vtd_page_walk_one(IOMMUTLBEntry *entry, in= t level, * @addr: base GPA addr to start the walk * @start: IOVA range start address * @end: IOVA range end address (start <=3D addr < end) - * @hook_fn: hook func to be called when detected page - * @private: private data to be passed into hook func * @read: whether parent level has read permission * @write: whether parent level has write permission - * @notify_unmap: whether we should notify invalid entries - * @aw: maximum address width + * @info: constant information for the page walk */ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start, - uint64_t end, vtd_page_walk_hook hook_fn, - void *private, uint32_t level, bool read, - bool write, bool notify_unmap, uint8_t aw) + uint64_t end, uint32_t level, bool read, + bool write, vtd_page_walk_info *info) { bool read_cur, write_cur, entry_valid; uint32_t offset; @@ -825,24 +839,24 @@ static int vtd_page_walk_level(dma_addr_t addr, uint6= 4_t start, =20 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, aw); - if (!entry_valid && !notify_unmap) { + 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, level, hook_fn, private); + ret =3D vtd_page_walk_one(&entry, level, info); if (ret < 0) { return ret; } } else { if (!entry_valid) { - if (notify_unmap) { + 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, level, hook_fn, priv= ate); + ret =3D vtd_page_walk_one(&entry, level, info); if (ret < 0) { return ret; } @@ -851,10 +865,9 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64= _t start, } goto next; } - ret =3D vtd_page_walk_level(vtd_get_slpte_addr(slpte, aw), iov= a, - MIN(iova_next, end), hook_fn, privat= e, - level - 1, read_cur, write_cur, - notify_unmap, aw); + 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; } @@ -883,6 +896,12 @@ static int vtd_page_walk(VTDContextEntry *ce, uint64_t= start, uint64_t end, { dma_addr_t addr =3D vtd_ce_get_slpt_base(ce); uint32_t level =3D vtd_ce_get_level(ce); + vtd_page_walk_info info =3D { + .hook_fn =3D hook_fn, + .private =3D private, + .notify_unmap =3D notify_unmap, + .aw =3D aw, + }; =20 if (!vtd_iova_range_check(start, ce, aw)) { return -VTD_FR_ADDR_BEYOND_MGAW; @@ -893,8 +912,7 @@ static int vtd_page_walk(VTDContextEntry *ce, uint64_t = start, uint64_t end, end =3D vtd_iova_limit(ce, aw); } =20 - return vtd_page_walk_level(addr, start, end, hook_fn, private, - level, true, true, notify_unmap, aw); + return vtd_page_walk_level(addr, start, end, level, true, true, &info); } =20 /* Map a device to its corresponding domain (context-entry) */ --=20 2.14.3