From patchwork Tue Sep 27 20:48:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 9352873 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 B8A56600CB for ; Tue, 27 Sep 2016 20:51:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AA86F29200 for ; Tue, 27 Sep 2016 20:51:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F4DB2920F; Tue, 27 Sep 2016 20:51:38 +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 5137829200 for ; Tue, 27 Sep 2016 20:51:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756245AbcI0UtU (ORCPT ); Tue, 27 Sep 2016 16:49:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53000 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756228AbcI0UtQ (ORCPT ); Tue, 27 Sep 2016 16:49:16 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (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 F147BC05A2B3; Tue, 27 Sep 2016 20:49:14 +0000 (UTC) Received: from localhost.redhat.com (vpn1-5-151.ams2.redhat.com [10.36.5.151]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8RKmhvR017556; Tue, 27 Sep 2016 16:49:09 -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: [RFC 04/11] iommu/dma: Allow MSI-only cookies Date: Tue, 27 Sep 2016 20:48:31 +0000 Message-Id: <1475009318-2617-5-git-send-email-eric.auger@redhat.com> In-Reply-To: <1475009318-2617-1-git-send-email-eric.auger@redhat.com> References: <1475009318-2617-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 27 Sep 2016 20:49:15 +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 From: Robin Murphy IOMMU domain users such as VFIO face a similar problem to DMA API ops with regard to mapping MSI messages in systems where the MSI write is subject to IOMMU translation. With the relevant infrastructure now in place for managed DMA domains, it's actually really simple for other users to piggyback off that and reap the benefits without giving up their own IOVA management, and without having to reinvent their own wheel in the MSI layer. Allow such users to opt into automatic MSI remapping by dedicating a region of their IOVA space to a managed cookie. Signed-off-by: Robin Murphy Signed-off-by: Eric Auger --- v1 -> v2: - add NULL last param to iommu_dma_init_domain - use cookie_iovad() - check against IOMMU_DOMAIN_MIXED domain type --- drivers/iommu/dma-iommu.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/linux/dma-iommu.h | 9 +++++++++ 2 files changed, 52 insertions(+) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index c5ab866..04bbc85 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -716,3 +716,46 @@ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) msg->address_lo += lower_32_bits(msi_page->iova); } } + +/** + * iommu_get_dma_msi_region_cookie - Configure a domain for MSI remapping only + * @domain: IOMMU domain to prepare + * @base: Base address of IOVA region to use as the MSI remapping aperture + * @size: Size of the desired MSI aperture + * + * Users who manage their own IOVA allocation and do not want DMA API support, + * but would still like to take advantage of automatic MSI remapping, can use + * this to initialise their own domain appropriately. + */ +int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain, + dma_addr_t base, u64 size) +{ + struct iova_domain *iovad; + int ret; + + if (domain->type != IOMMU_DOMAIN_MIXED) + return -EINVAL; + + /* check the iova domain intersects the MSI window */ + if (iommu_domain_msi_aperture_valid(domain) && + (domain->msi_geometry.aperture_end < base || + domain->msi_geometry.aperture_start > base + size - 1)) + return -EINVAL; + + ret = iommu_get_dma_cookie(domain); + if (ret) + return ret; + + ret = iommu_dma_init_domain(domain, base, size, NULL); + if (ret) { + iommu_put_dma_cookie(domain); + return ret; + } + + iovad = cookie_iovad(domain); + if (base < U64_MAX - size) + reserve_iova(iovad, iova_pfn(iovad, base + size), ULONG_MAX); + + return 0; +} +EXPORT_SYMBOL(iommu_get_dma_msi_region_cookie); diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h index 32c5890..1c55413 100644 --- a/include/linux/dma-iommu.h +++ b/include/linux/dma-iommu.h @@ -67,6 +67,9 @@ int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr); /* The DMA API isn't _quite_ the whole story, though... */ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg); +int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain, + dma_addr_t base, u64 size); + #else struct iommu_domain; @@ -90,6 +93,12 @@ static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) { } +static inline int iommu_get_dma_msi_region_cookie(struct iommu_domain *domain, + dma_addr_t base, u64 size) +{ + return -ENODEV; +} + #endif /* CONFIG_IOMMU_DMA */ #endif /* __KERNEL__ */ #endif /* __DMA_IOMMU_H */