From patchwork Thu Apr 7 17:42:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 8775341 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1E7509F36E for ; Thu, 7 Apr 2016 17:44:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 284C320251 for ; Thu, 7 Apr 2016 17:44:13 +0000 (UTC) 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.kernel.org (Postfix) with ESMTPS id 2DD7B201CD for ; Thu, 7 Apr 2016 17:44:12 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aoDxB-0006P3-A8; Thu, 07 Apr 2016 17:42:49 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aoDww-0006F3-ND for linux-arm-kernel@lists.infradead.org; Thu, 07 Apr 2016 17:42:35 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3DB0C28; Thu, 7 Apr 2016 10:41:03 -0700 (PDT) Received: from e104324-lin.cambridge.arm.com (e104324-lin.cambridge.arm.com [10.1.205.154]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id CF1643F25E; Thu, 7 Apr 2016 10:42:12 -0700 (PDT) From: Robin Murphy To: joro@8bytes.org, will.deacon@arm.com Subject: [PATCH 0/5] Introduce per-domain page sizes Date: Thu, 7 Apr 2016 18:42:03 +0100 Message-Id: X-Mailer: git-send-email 2.7.3.dirty X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160407_104234_845142_E5E76A8F X-CRM114-Status: GOOD ( 13.87 ) X-Spam-Score: -7.9 (-------) 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: laurent.pinchart+renesas@ideasonboard.com, dianders@chromium.org, iommu@lists.linux-foundation.org, linux-arm-kernel@lists.infradead.org, treding@nvidia.com, mitchelh@codeaurora.org, brian.starkey@arm.com, yong.wu@mediatek.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-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi all, Since this area seems to be in vogue at the moment, here's what I was working on when the related patches[1][2] popped up, which happens to be more or less the intersection of both. As I recycled some of Will's old series as a starting point, I've retained the cleanup patches from that with their original acks - hope that's OK. Fortunately, this already looks rather like parts of Joerg's plan[3], so I hope it's a suitable first step. Below is a quick hacked-up example of the kind of caller-controlled special use-case alluded to, using the SMMU/HDLCD combo on Juno - for a 'real' implementation of this we'd want the group-based domain allocation call so the driver could throw the device at that and get its own non-default DMA ops domain to play with. Robin. [1]:http://thread.gmane.org/gmane.linux.kernel.iommu/12774 [2]:http://thread.gmane.org/gmane.linux.kernel.iommu/12901 [3]:http://article.gmane.org/gmane.linux.kernel.iommu/12937 Robin Murphy (4): iommu: of: enforce const-ness of struct iommu_ops iommu: Allow selecting page sizes per domain iommu/dma: Finish optimising higher-order allocations iommu/arm-smmu: Use per-domain page sizes. Will Deacon (1): iommu: remove unused priv field from struct iommu_ops arch/arm/include/asm/dma-mapping.h | 2 +- arch/arm/mm/dma-mapping.c | 6 +++--- arch/arm64/include/asm/dma-mapping.h | 2 +- arch/arm64/mm/dma-mapping.c | 8 ++++---- drivers/iommu/arm-smmu-v3.c | 19 +++++++++--------- drivers/iommu/arm-smmu.c | 26 +++++++++++++----------- drivers/iommu/dma-iommu.c | 39 +++++++++++++++++++++++++++--------- drivers/iommu/iommu.c | 22 +++++++++++--------- drivers/iommu/mtk_iommu.c | 2 +- drivers/iommu/of_iommu.c | 14 ++++++------- drivers/of/device.c | 2 +- drivers/vfio/vfio_iommu_type1.c | 2 +- include/linux/dma-iommu.h | 4 ++-- include/linux/dma-mapping.h | 2 +- include/linux/iommu.h | 5 ++--- include/linux/of_iommu.h | 8 ++++---- 16 files changed, 93 insertions(+), 70 deletions(-) --->8--- Acked-by: Will Deacon diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 56b829f..0da0f4b 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) { struct hdlcd_drm_private *hdlcd = drm->dev_private; struct platform_device *pdev = to_platform_device(drm->dev); + struct iommu_domain *dom; struct resource *res; u32 version; int ret; @@ -79,6 +81,21 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) if (ret) goto setup_fail; + /* + * EXAMPLE: Let's say that if we're using an SMMU, we'd rather waste + * a little memory by forcing DMA allocation and mapping to section + * granularity so the whole buffer fits in the TLBs, than waste power + * by having the SMMU constantly walking page tables all the time we're + * scanning out. In this case we know our default domain isn't shared + * with any other devices, so we can cheat and mangle that directly. + */ + dom = iommu_get_domain_for_dev(drm->dev); + if (dom) { + dom->pgsize_bitmap &= ~(SZ_1M - 1); + if (!dom->pgsize_bitmap) + goto setup_fail; + } + ret = hdlcd_setup_crtc(drm); if (ret < 0) { DRM_ERROR("failed to create crtc\n");