From nobody Sun Feb 8 12:37:58 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 1532378646621792.6032846079263; Mon, 23 Jul 2018 13:44:06 -0700 (PDT) Received: from localhost ([::1]:36472 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhhgb-0006gx-Hz for importer@patchew.org; Mon, 23 Jul 2018 16:44:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41204) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhhIo-0001tg-4c for qemu-devel@nongnu.org; Mon, 23 Jul 2018 16:19:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fhhIm-0003GH-JT for qemu-devel@nongnu.org; Mon, 23 Jul 2018 16:19:30 -0400 Received: from mail-oi0-x233.google.com ([2607:f8b0:4003:c06::233]:44630) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fhhIm-0003FU-9I; Mon, 23 Jul 2018 16:19:28 -0400 Received: by mail-oi0-x233.google.com with SMTP id s198-v6so3458464oih.11; Mon, 23 Jul 2018 13:19:28 -0700 (PDT) Received: from localhost (76-251-165-188.lightspeed.austtx.sbcglobal.net. [76.251.165.188]) by smtp.gmail.com with ESMTPSA id i204-v6sm19817120oia.41.2018.07.23.13.19.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Jul 2018 13:19:26 -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=JCJJqx1WZVulnTd+qY2Ldfx2VPksywZR7hBjYoCb3hM=; b=OiBmzysLLzMVdjFSWZtwQmhiWzdnUHTZKk6zk2f/RCtcipWgvQmXmito6nW27iv6VO vSIzibX+hpSsHISDwBJ5GDjQzI94XOa/V+vOSzmnPrF2LzFrEJBVzvZugakzanQppYz6 LHo2KJUSWRvnecdNAHW37X76KnLAjymzvlne0rvOsLSgmteuBXojIffwj5FPreL25Lm/ b6hKkgntHsHlJYrdeb/01hlk6MkqcaDli9l4/3OmwHSct9vShHTYPtplpuxTRTVqiKEt JNbODOb/ttSFE9cFOqvWtQz20ujbDOSuldytRxzV2TZFcbFJNsw4VagSbC01B97braNR aaMQ== 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=JCJJqx1WZVulnTd+qY2Ldfx2VPksywZR7hBjYoCb3hM=; b=XGuNQRvgLZA3GrBAuH96qckEF3DrNiocvc3AQ3G0nduP6Jlm4/6vtiCokXHtAoKNIv 8eWsyoVTUZP5VZuXru28aKjS89Jjs2aUpjfFvUs8SDzJrkwUeiPjFJ4hLiWz7Sap2PSx QBQaJv/MAOnEJRyO8xYDqEG3IrF2WDqSBBEcW6U5On63tRha/0TjH7wkwXb0V5XZdN8o IoWUbgfb0F8CwYOipPiK+2aODvLaj6t+9whFHOTpy/V/iDl14F0HuBcKg4EK5pFzN+Rp fojMVsRftrtBnIN0YhcSt/a3osl0YuvTjamcC7suS2rBcwub9obrbbmILyaF6NSoaSRF DS8Q== X-Gm-Message-State: AOUpUlH4OP8remUwm+1BhbL1TyjM4NmSTuuDIAtxUCdbuRnCtmylx0j2 jWJhfgpUWjfXIWvE4+xl4tLrefBGKok= X-Google-Smtp-Source: AAOMgpdZlwqz7QNPnCY7NENrVfalAEZki+U6Tjj1H0IzbK+DPEiPfTjHyFo6/kOSQ0Dg4OLsmHlrJw== X-Received: by 2002:aca:edc1:: with SMTP id l184-v6mr273623oih.65.1532377167100; Mon, 23 Jul 2018 13:19:27 -0700 (PDT) From: Michael Roth To: qemu-devel@nongnu.org Date: Mon, 23 Jul 2018 15:16:38 -0500 Message-Id: <20180723201748.25573-30-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com> References: <20180723201748.25573-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::233 Subject: [Qemu-devel] [PATCH 29/99] 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 38ccc741f9..e247269659 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 @@ -2924,8 +2938,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.17.1