From nobody Mon Feb 9 23:01:04 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; dkim=fail; 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 1529376695745671.1866486710225; Mon, 18 Jun 2018 19:51:35 -0700 (PDT) Received: from localhost ([::1]:38770 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fV6k2-0002bI-U5 for importer@patchew.org; Mon, 18 Jun 2018 22:51:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47465) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fV5kA-0003Xa-6N for qemu-devel@nongnu.org; Mon, 18 Jun 2018 21:47:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fV5k8-000184-64 for qemu-devel@nongnu.org; Mon, 18 Jun 2018 21:47:38 -0400 Received: from mail-oi0-x22d.google.com ([2607:f8b0:4003:c06::22d]:32792) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fV5k7-00017x-Vb; Mon, 18 Jun 2018 21:47:36 -0400 Received: by mail-oi0-x22d.google.com with SMTP id c6-v6so16702939oiy.0; Mon, 18 Jun 2018 18:47:35 -0700 (PDT) Received: from localhost (76-251-165-188.lightspeed.austtx.sbcglobal.net. [76.251.165.188]) by smtp.gmail.com with ESMTPSA id w189-v6sm7475895oie.45.2018.06.18.18.47.33 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 18 Jun 2018 18:47:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=RW8WUqC+0tSP59/140BG9XPqLyfx4dq5WVNsscSVHSc=; b=NmjdhFWI2DWNVAzOgZaMDJQSUmHMyLhrGVJWMF1s29wNfVnQ17aZolHeWTk8AYbGOL w+itKYtrhPIHDrPRlmys5fyBNRWINDzYswAoA/AsuH2O2iB/hREJdBe++kNIL7l7Jd6C tJVQd4I97w/5woxbs0WwqOPf6PJtx9bSzBScopR3igIEmQ+Dsn/inTP5CCKg4q7DRHdr zR9qqvfv8bXl+HYVcndKgFWExrH9PbzNVDzNZq2FePfILagzW0mIU4CtKTRFMuybmOB2 N8iwpHgwaYju2uP4/uox68RJmN8mS9ZNomB8EUnWtDv+kxA2fLlCFkfvRN3RlQbAMo0I vP8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=RW8WUqC+0tSP59/140BG9XPqLyfx4dq5WVNsscSVHSc=; b=tUtNXz5DzqU7pHoz1P+d+UVj2RX+PYLnDMCcGfTjL1R7VFQ8SMTT9qRrOb5LBmQuR8 jENoUF7Xgv+P+F6jbTsTUfj3cTDKc/VW91cR/0XalUVH63ae1YZGJ6z2D4QWslTFZH+C OVKWrwIzQIz743iqU8pFVMqTYPxtelaS3N0MVs0Whj+7a10lQey3n3tTUx6qCKoKZkOT hvuUjVQ2rs5979+ODE5ahT3YSqBcblV6JwukMlYaFUu2c6NmDW2yx5JuMatzdvOvxl80 kj2IlSviHRviQSBz7JCRzgoCXI4R2kKYKgjglX5FSXymwMcdWRajmoEJ8vI6JzBpP5f/ VOwg== X-Gm-Message-State: APt69E03tPTelwugkXtqFcPd299bWf+KWpXiw/m9b5aglSy5qXXAi45X 9f6dl0Yx5d70Pkx3OxqVtNMCbx98kkk= X-Google-Smtp-Source: ADUXVKJBmHIwkACoSN7Fhq0/iaT3i7iluKQhq2ENlE+9V9XIyuoBBZ4k62MBTpw35iWMqwsLBgAVTw== X-Received: by 2002:aca:484d:: with SMTP id v74-v6mr7683226oia.354.1529372854729; Mon, 18 Jun 2018 18:47:34 -0700 (PDT) From: Michael Roth To: qemu-devel@nongnu.org Date: Mon, 18 Jun 2018 20:42:58 -0500 Message-Id: <20180619014319.28272-93-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180619014319.28272-1-mdroth@linux.vnet.ibm.com> References: <20180619014319.28272-1-mdroth@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4003:c06::22d Subject: [Qemu-devel] [PATCH 092/113] 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: qemu-stable@nongnu.org, Peter Xu , "Michael S . Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Peter Xu 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. CC: QEMU Stable Signed-off-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin (cherry picked from commit fe215b0cbb8c1f4b4af0a64aa5c02042080dd537) Signed-off-by: Michael Roth --- hw/i386/intel_iommu.c | 84 +++++++++++++++++++++++++++++++----------------= ---- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 3715fa327b..e059bfd577 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -748,9 +748,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); @@ -763,17 +781,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; @@ -823,24 +837,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; } @@ -849,10 +863,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; } @@ -871,28 +884,24 @@ next: * @ce: context entry to walk upon * @start: IOVA address to start the walk * @end: IOVA range end address (start <=3D addr < end) - * @hook_fn: the hook that to be called for each detected area - * @private: private data for the hook function - * @aw: maximum address width + * @info: page walking information struct */ static int vtd_page_walk(VTDContextEntry *ce, uint64_t start, uint64_t end, - vtd_page_walk_hook hook_fn, void *private, - bool notify_unmap, uint8_t aw) + vtd_page_walk_info *info) { dma_addr_t addr =3D vtd_ce_get_slpt_base(ce); uint32_t level =3D vtd_ce_get_level(ce); =20 - if (!vtd_iova_range_check(start, ce, aw)) { + if (!vtd_iova_range_check(start, ce, info->aw)) { return -VTD_FR_ADDR_BEYOND_MGAW; } =20 - if (!vtd_iova_range_check(end, ce, aw)) { + if (!vtd_iova_range_check(end, ce, info->aw)) { /* Fix end so that it reaches the maximum */ - end =3D vtd_iova_limit(ce, aw); + end =3D vtd_iova_limit(ce, info->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) */ @@ -1449,14 +1458,19 @@ static void vtd_iotlb_page_invalidate_notify(IntelI= OMMUState *s, vtd_as->devfn, &ce); if (!ret && domain_id =3D=3D VTD_CONTEXT_ENTRY_DID(ce.hi)) { if (vtd_as_has_map_notifier(vtd_as)) { + vtd_page_walk_info info =3D { + .hook_fn =3D vtd_page_invalidate_notify_hook, + .private =3D (void *)&vtd_as->iommu, + .notify_unmap =3D true, + .aw =3D s->aw_bits, + }; + /* * As long as we have MAP notifications registered in * any of our IOMMU notifiers, we need to sync the * shadow page table. */ - vtd_page_walk(&ce, addr, addr + size, - vtd_page_invalidate_notify_hook, - (void *)&vtd_as->iommu, true, s->aw_bits); + vtd_page_walk(&ce, addr, addr + size, &info); } else { /* * For UNMAP-only notifiers, we don't need to walk the @@ -2917,8 +2931,14 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iomm= u_mr, IOMMUNotifier *n) ce.hi, ce.lo); if (vtd_as_has_map_notifier(vtd_as)) { /* This is required only for MAP typed notifiers */ - vtd_page_walk(&ce, 0, ~0ULL, vtd_replay_hook, (void *)n, false, - s->aw_bits); + vtd_page_walk_info info =3D { + .hook_fn =3D vtd_replay_hook, + .private =3D (void *)n, + .notify_unmap =3D false, + .aw =3D s->aw_bits, + }; + + vtd_page_walk(&ce, 0, ~0ULL, &info); } } else { trace_vtd_replay_ce_invalid(bus_n, PCI_SLOT(vtd_as->devfn), --=20 2.11.0