From patchwork Mon May 9 11:45:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 9045451 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 8D61BBF29F for ; Mon, 9 May 2016 11:48:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 64B3F20115 for ; Mon, 9 May 2016 11:48:08 +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 9BEA6200C6 for ; Mon, 9 May 2016 11:48:03 +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 1azjdW-0005Q7-DE; Mon, 09 May 2016 11:46:06 +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 1azjdT-0005LO-J0 for linux-arm-kernel@lists.infradead.org; Mon, 09 May 2016 11:46:04 +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 8E61B3C; Mon, 9 May 2016 04:45:52 -0700 (PDT) Received: from [10.1.205.154] (e104324-lin.cambridge.arm.com [10.1.205.154]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id AE3173F218; Mon, 9 May 2016 04:45:40 -0700 (PDT) Subject: Re: [PATCH 0/5] Introduce per-domain page sizes To: Joerg Roedel References: <20160509112138.GB13275@8bytes.org> From: Robin Murphy Message-ID: <57307863.1070706@arm.com> Date: Mon, 9 May 2016 12:45:39 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.2 MIME-Version: 1.0 In-Reply-To: <20160509112138.GB13275@8bytes.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160509_044603_659478_257E90C5 X-CRM114-Status: GOOD ( 22.80 ) X-Spam-Score: -9.0 (---------) 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, will.deacon@arm.com, dianders@chromium.org, iommu@lists.linux-foundation.org, treding@nvidia.com, brian.starkey@arm.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-6.3 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 Joerg, On 09/05/16 12:21, Joerg Roedel wrote: > On Thu, Apr 07, 2016 at 06:42:03PM +0100, Robin Murphy wrote: >> 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 > > Okay, I am still no happy that this lifts the requirements of the > iommu-api for the arm-smmu driver. But to get there we need more core > changes and this code is a step in the right direction, so I applied it. Thanks a lot! I was expecting to pick this up again after the merge window and post an updated version then; as you may already have found, patch 5 conflicts somewhat with the SMMUv2 context format changes in Will's updates branch. The correct resolution requires a bit of rewriting, so below is what that patch looks like when rebased on top of Will's branch. If you'd prefer it in actual merge resolution format, shout and I'll give that a go. Thanks, Robin. --->8--- commit a940dae4e124523bc1cf282c8f36c79f960a0805 Author: Robin Murphy Date: Mon Mar 14 14:25:07 2016 +0000 iommu/arm-smmu: Use per-domain page sizes. Now that we can accurately reflect the context format we choose for each domain, do that instead of imposing the global lowest-common-denominator restriction and potentially ending up with nothing. We currently have a strict 1:1 correspondence between domains and context banks, so we don't need to entertain the possibility of multiple formats _within_ a domain. Signed-off-by: Will Deacon [rm: split from original patch, added SMMUv3] Signed-off-by: Robin Murphy .tlb = &arm_smmu_gather_ops, @@ -963,8 +962,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, goto out_clear_smmu; } - /* Update our support page sizes to reflect the page table format */ - arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; + /* Update the domain's page sizes to reflect the page table format */ + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; /* Initialise the context bank with our page table cfg */ arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg); @@ -1793,19 +1792,23 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) } /* Now we've corralled the various formats, what'll it do? */ - size = 0; if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_S) - size |= SZ_4K | SZ_64K | SZ_1M | SZ_16M; + smmu->pgsize_bitmap |= SZ_4K | SZ_64K | SZ_1M | SZ_16M; if (smmu->features & (ARM_SMMU_FEAT_FMT_AARCH32_L | ARM_SMMU_FEAT_FMT_AARCH64_4K)) - size |= SZ_4K | SZ_2M | SZ_1G; + smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G; if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH64_16K) - size |= SZ_16K | SZ_32M; + smmu->pgsize_bitmap |= SZ_16K | SZ_32M; if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH64_64K) - size |= SZ_64K | SZ_512M; + smmu->pgsize_bitmap |= SZ_64K | SZ_512M; + + if (arm_smmu_ops.pgsize_bitmap == -1UL) + arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap; + else + arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap; + dev_notice(smmu->dev, "\tSupported page sizes: 0x%08lx\n", + smmu->pgsize_bitmap); - arm_smmu_ops.pgsize_bitmap &= size; - dev_notice(smmu->dev, "\tSupported page sizes: 0x%08lx\n", size); if (smmu->features & ARM_SMMU_FEAT_TRANS_S1) dev_notice(smmu->dev, "\tStage-1: %lu-bit VA -> %lu-bit IPA\n", diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 4ff73ff64e49..ebab33e77d67 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -590,6 +590,7 @@ struct arm_smmu_device { unsigned long ias; /* IPA */ unsigned long oas; /* PA */ + unsigned long pgsize_bitmap; #define ARM_SMMU_MAX_ASIDS (1 << 16) unsigned int asid_bits; @@ -1516,8 +1517,6 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain, return 0; } -static struct iommu_ops arm_smmu_ops; - static int arm_smmu_domain_finalise(struct iommu_domain *domain) { int ret; @@ -1555,7 +1554,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain) } pgtbl_cfg = (struct io_pgtable_cfg) { - .pgsize_bitmap = arm_smmu_ops.pgsize_bitmap, + .pgsize_bitmap = smmu->pgsize_bitmap, .ias = ias, .oas = oas, .tlb = &arm_smmu_gather_ops, @@ -1566,7 +1565,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain) if (!pgtbl_ops) return -ENOMEM; - arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; smmu_domain->pgtbl_ops = pgtbl_ops; ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg); @@ -2410,7 +2409,6 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu) { u32 reg; bool coherent; - unsigned long pgsize_bitmap = 0; /* IDR0 */ reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0); @@ -2541,13 +2539,16 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu) /* Page sizes */ if (reg & IDR5_GRAN64K) - pgsize_bitmap |= SZ_64K | SZ_512M; + smmu->pgsize_bitmap |= SZ_64K | SZ_512M; if (reg & IDR5_GRAN16K) - pgsize_bitmap |= SZ_16K | SZ_32M; + smmu->pgsize_bitmap |= SZ_16K | SZ_32M; if (reg & IDR5_GRAN4K) - pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G; + smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G; - arm_smmu_ops.pgsize_bitmap &= pgsize_bitmap; + if (arm_smmu_ops.pgsize_bitmap == -1UL) + arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap; + else + arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap; /* Output address size */ switch (reg & IDR5_OAS_MASK << IDR5_OAS_SHIFT) { diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 0bda956a025c..bf30490d6b18 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -343,6 +343,7 @@ struct arm_smmu_device { unsigned long va_size; unsigned long ipa_size; unsigned long pa_size; + unsigned long pgsize_bitmap; u32 num_global_irqs; u32 num_context_irqs; @@ -388,8 +389,6 @@ struct arm_smmu_domain { struct iommu_domain domain; }; -static struct iommu_ops arm_smmu_ops; - static DEFINE_SPINLOCK(arm_smmu_devices_lock); static LIST_HEAD(arm_smmu_devices); @@ -949,7 +948,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, } pgtbl_cfg = (struct io_pgtable_cfg) { - .pgsize_bitmap = arm_smmu_ops.pgsize_bitmap, + .pgsize_bitmap = smmu->pgsize_bitmap, .ias = ias, .oas = oas,