From patchwork Thu Oct 6 08:45:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 9364439 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 7B41C607D3 for ; Thu, 6 Oct 2016 09:36:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6C8C522AFC for ; Thu, 6 Oct 2016 09:36:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6103F28E74; Thu, 6 Oct 2016 09:36:29 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0CA1422AFC for ; Thu, 6 Oct 2016 09:36:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S942480AbcJFIqI (ORCPT ); Thu, 6 Oct 2016 04:46:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39314 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S942199AbcJFIqF (ORCPT ); Thu, 6 Oct 2016 04:46:05 -0400 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 3D302A0B55; Thu, 6 Oct 2016 08:46:05 +0000 (UTC) Received: from localhost.redhat.com (vpn1-6-233.ams2.redhat.com [10.36.6.233]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u968jZtN011450; Thu, 6 Oct 2016 04:46:00 -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 Cc: kvm@vger.kernel.org, drjones@redhat.com, linux-kernel@vger.kernel.org, Bharat.Bhushan@freescale.com, pranav.sawargaonkar@gmail.com, p.fedin@samsung.com, iommu@lists.linux-foundation.org, Jean-Philippe.Brucker@arm.com, yehuday@marvell.com, Manish.Jaggi@caviumnetworks.com Subject: [PATCH v13 05/15] genirq/msi: msi_doorbell_calc_pages Date: Thu, 6 Oct 2016 08:45:21 +0000 Message-Id: <1475743531-4780-6-git-send-email-eric.auger@redhat.com> In-Reply-To: <1475743531-4780-1-git-send-email-eric.auger@redhat.com> References: <1475743531-4780-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.25]); Thu, 06 Oct 2016 08:46:05 +0000 (UTC) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP msi_doorbell_calc_pages() sum up the number of iommu pages of a given order 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. Note this requirement cannot be computed at MSI doorbell registration time since the IOMMU page order is not known. Signed-off-by: Eric Auger --- v11 -> v12: - fix style issues: remove useless line break, remove pointless braces, fix kernel-doc comments - reword commit message - rename msi_doorbell_pages into msi_doorbell_calc_pages - rename static compute* functions v10: creation --- include/linux/msi-doorbell.h | 15 +++++++++++ kernel/irq/msi-doorbell.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/include/linux/msi-doorbell.h b/include/linux/msi-doorbell.h index c18a382..f1106cb 100644 --- a/include/linux/msi-doorbell.h +++ b/include/linux/msi-doorbell.h @@ -54,6 +54,15 @@ void msi_doorbell_unregister_global(struct msi_doorbell_info *db); */ bool msi_doorbell_safe(void); +/** + * msi_doorbell_calc_pages - compute the number of pages + * requested to map all the registered doorbells + * @order: iommu page order + * + * Return: the number of requested pages + */ +int msi_doorbell_calc_pages(unsigned int order); + #else static inline int @@ -72,6 +81,12 @@ static inline bool msi_doorbell_safe(void) { return true; } + +static inline int msi_doorbell_calc_pages(unsigned int order) +{ + return 0; +} + #endif /* CONFIG_MSI_DOORBELL */ #endif diff --git a/kernel/irq/msi-doorbell.c b/kernel/irq/msi-doorbell.c index 60a262a..d1cc525 100644 --- a/kernel/irq/msi-doorbell.c +++ b/kernel/irq/msi-doorbell.c @@ -96,3 +96,67 @@ bool msi_doorbell_safe(void) return !nb_unsafe_doorbells; } EXPORT_SYMBOL_GPL(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 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 msi_doorbell_calc_pages(unsigned int order) +{ + struct msi_doorbell *db; + int ret = 0; + + mutex_lock(&msi_doorbell_mutex); + list_for_each_entry(db, &msi_doorbell_list, next) + ret += calc_dbinfo_reqs(&db->info, order); + + mutex_unlock(&msi_doorbell_mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(msi_doorbell_calc_pages);