From patchwork Wed Oct 12 13:22:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 9373005 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 63B3660865 for ; Wed, 12 Oct 2016 13:25:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53AF328B6F for ; Wed, 12 Oct 2016 13:25:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 48396295CF; Wed, 12 Oct 2016 13:25:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5248A28CAE for ; Wed, 12 Oct 2016 13:25:57 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1buJWP-0006a9-9W; Wed, 12 Oct 2016 13:24:37 +0000 Received: from mx1.redhat.com ([209.132.183.28]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1buJV4-0005pz-Gk for linux-arm-kernel@lists.infradead.org; Wed, 12 Oct 2016 13:23:15 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6A06083F3B; Wed, 12 Oct 2016 13:22:56 +0000 (UTC) Received: from localhost.redhat.com (vpn1-6-235.ams2.redhat.com [10.36.6.235]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9CDMQCj010906; Wed, 12 Oct 2016 09:22:52 -0400 From: Eric Auger To: eric.auger@redhat.com, eric.auger.pro@gmail.com, christoffer.dall@linaro.org, marc.zyngier@arm.com, robin.murphy@arm.com, alex.williamson@redhat.com, will.deacon@arm.com, joro@8bytes.org, tglx@linutronix.de, jason@lakedaemon.net, linux-arm-kernel@lists.infradead.org Subject: [PATCH v14 05/16] iommu/dma: Introduce iommu_calc_msi_resv Date: Wed, 12 Oct 2016 13:22:13 +0000 Message-Id: <1476278544-3397-6-git-send-email-eric.auger@redhat.com> In-Reply-To: <1476278544-3397-1-git-send-email-eric.auger@redhat.com> References: <1476278544-3397-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 12 Oct 2016 13:22:56 +0000 (UTC) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161012_062314_671169_7B92584E X-CRM114-Status: GOOD ( 15.53 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: drjones@redhat.com, kvm@vger.kernel.org, Jean-Philippe.Brucker@arm.com, Manish.Jaggi@caviumnetworks.com, p.fedin@samsung.com, linux-kernel@vger.kernel.org, Bharat.Bhushan@freescale.com, iommu@lists.linux-foundation.org, pranav.sawargaonkar@gmail.com, yehuday@marvell.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP iommu_calc_msi_resv() sum up the number of iommu pages of the lowest order supported by the iommu domain requested to map all the registered doorbells. This function will allow to dimension the intermediate physical address (IPA) aperture requested to map the MSI doorbells. Signed-off-by: Eric Auger --- v13 -> v14 - name and proto changed, moved to dma-iommu --- drivers/iommu/dma-iommu.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/dma-iommu.h | 11 +++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index d8a7d86..3a4b73b 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -830,3 +830,73 @@ bool iommu_msi_doorbell_safe(void) return !nb_unsafe_doorbells; } EXPORT_SYMBOL_GPL(iommu_msi_doorbell_safe); + +/** + * calc_region_reqs - compute the number of pages requested to map a region + * + * @addr: physical base address of the region + * @size: size of the region + * @order: the page order + * + * Return: the number of requested pages to map this region + */ +static int calc_region_reqs(phys_addr_t addr, size_t size, unsigned int order) +{ + phys_addr_t offset, granule; + unsigned int nb_pages; + + granule = (uint64_t)(1 << order); + offset = addr & (granule - 1); + size = ALIGN(size + offset, granule); + nb_pages = size >> order; + + return nb_pages; +} + +/** + * calc_dbinfo_reqs - compute the number of pages requested to map a given + * MSI doorbell + * + * @dbi: doorbell info descriptor + * @order: page order + * + * Return: the number of requested pages to map this doorbell + */ +static int calc_dbinfo_reqs(struct iommu_msi_doorbell_info *dbi, + unsigned int order) +{ + int ret = 0; + + if (!dbi->doorbell_is_percpu) { + ret = calc_region_reqs(dbi->global_doorbell, dbi->size, order); + } else { + phys_addr_t __percpu *pbase; + int cpu; + + for_each_possible_cpu(cpu) { + pbase = per_cpu_ptr(dbi->percpu_doorbells, cpu); + ret += calc_region_reqs(*pbase, dbi->size, order); + } + } + return ret; +} + +int iommu_calc_msi_resv(struct iommu_domain *domain) +{ + unsigned long order = __ffs(domain->pgsize_bitmap); + struct iommu_msi_doorbell *db; + phys_addr_t granule; + int size = 0; + + mutex_lock(&iommu_msi_doorbell_mutex); + list_for_each_entry(db, &iommu_msi_doorbell_list, next) + size += calc_dbinfo_reqs(&db->info, order); + + mutex_unlock(&iommu_msi_doorbell_mutex); + + granule = (uint64_t)(1 << order); + domain->msi_resv.size = size * granule; + domain->msi_resv.alignment = granule; + + return 0; +} diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h index 9640a27..95875c8 100644 --- a/include/linux/dma-iommu.h +++ b/include/linux/dma-iommu.h @@ -97,6 +97,16 @@ void iommu_msi_doorbell_free(struct iommu_msi_doorbell_info *db); */ bool iommu_msi_doorbell_safe(void); +/** + * iommu_calc_msi_resv - compute the number of pages of the lowest order + * supported by @domain, requested to map all the registered doorbells. + * + * @domain: iommu_domain + * @msi_resv: MSI reserved window requirements + * + */ +int iommu_calc_msi_resv(struct iommu_domain *domain); + #else struct iommu_domain; @@ -139,7 +149,6 @@ static inline bool iommu_msi_doorbell_safe(void) { return false; } - #endif /* CONFIG_IOMMU_DMA */ #endif /* __KERNEL__ */ #endif /* __DMA_IOMMU_H */