From patchwork Mon Jul 27 12:29:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell King X-Patchwork-Id: 6873301 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 702C69F39D for ; Mon, 27 Jul 2015 12:33:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 88E9F2043C for ; Mon, 27 Jul 2015 12:33:10 +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 081BB20445 for ; Mon, 27 Jul 2015 12:33:05 +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 1ZJhYd-00053z-CL; Mon, 27 Jul 2015 12:31:03 +0000 Received: from pandora.arm.linux.org.uk ([2001:4d48:ad52:3201:214:fdff:fe10:1be6]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZJhXo-0002wQ-4q for linux-arm-kernel@lists.infradead.org; Mon, 27 Jul 2015 12:30:15 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=arm.linux.org.uk; s=pandora-2014; h=Date:Sender:Message-Id:Content-Type:Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References:In-Reply-To; bh=LFr/mpawDd85c8UJOSISa+ujkwEBOzOSNWIhssKb7MM=; b=agXhu1KvkoITVGjcg3tFdkBywsPpAbNAf1LwxlbLoGlUunVag8i3nwULCcIb21gNgU1tTlianWR/85aiR6nRMRvXsMrz+2cSE5VrK99cjZnD1UgwClYX1figpTWXS841Wr3TdQ7WJJ/i+n7PVPU54HCzCBP+m9yhJn+rBD1wqHA=; Received: from e0022681537dd.dyn.arm.linux.org.uk ([2001:4d48:ad52:3201:222:68ff:fe15:37dd]:36782 helo=rmk-PC.arm.linux.org.uk) by pandora.arm.linux.org.uk with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1ZJhXA-00070P-B9; Mon, 27 Jul 2015 13:29:32 +0100 Received: from rmk by rmk-PC.arm.linux.org.uk with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1ZJhX4-00047l-98; Mon, 27 Jul 2015 13:29:26 +0100 In-Reply-To: <20150727122824.GH7557@n2100.arm.linux.org.uk> References: <20150727122824.GH7557@n2100.arm.linux.org.uk> From: Russell King To: iommu@lists.linux-foundation.org, linux-arm-kernel@lists.infradead.org, linux-tegra@vger.kernel.org Subject: [PATCH 08/18] iommu: tegra-smmu: store struct page pointer for page tables MIME-Version: 1.0 Content-Disposition: inline Message-Id: Date: Mon, 27 Jul 2015 13:29:26 +0100 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150727_053013_023603_D47B3075 X-CRM114-Status: GOOD ( 15.92 ) X-Spam-Score: -2.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: Alexandre Courbot , Joerg Roedel , Stephen Warren , Thierry Reding , Hiroshi Doyu 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.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,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 Store the struct page pointer for the second level page tables, rather than working back from the page directory entry. This is necessary as we want to eliminate the use of physical addresses used with arch-private functions, switching instead to use the streaming DMA API. Signed-off-by: Russell King --- drivers/iommu/tegra-smmu.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index bbff5b647183..8ec5ac45caab 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -41,6 +41,7 @@ struct tegra_smmu_as { struct tegra_smmu *smmu; unsigned int use_count; struct page *count; + struct page **pts; struct page *pd; unsigned id; u32 attr; @@ -271,6 +272,14 @@ static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type) return NULL; } + as->pts = kcalloc(SMMU_NUM_PDE, sizeof(*as->pts), GFP_KERNEL); + if (!as->pts) { + __free_page(as->count); + __free_page(as->pd); + kfree(as); + return NULL; + } + /* clear PDEs */ pd = page_address(as->pd); SetPageReserved(as->pd); @@ -487,14 +496,11 @@ static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova, { unsigned int pd_index = iova_pd_index(iova); struct page *pt_page; - u32 *pd; - pd = page_address(as->pd); - - if (!pd[pd_index]) + pt_page = as->pts[pd_index]; + if (!pt_page) return NULL; - pt_page = pfn_to_page(pd[pd_index] & as->smmu->pfn_mask); *pagep = pt_page; return tegra_smmu_pte_offset(pt_page, iova); @@ -509,7 +515,7 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, struct page *page; unsigned int i; - if (pd[pde] == 0) { + if (!as->pts[pde]) { page = alloc_page(GFP_KERNEL | __GFP_DMA); if (!page) return NULL; @@ -520,6 +526,8 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, for (i = 0; i < SMMU_NUM_PTE; i++) pt[i] = 0; + as->pts[pde] = page; + smmu->soc->ops->flush_dcache(page, 0, SMMU_SIZE_PT); pd[pde] = SMMU_MK_PDE(page, SMMU_PDE_ATTR | SMMU_PDE_NEXT); @@ -529,7 +537,7 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, smmu_flush_tlb_section(smmu, as->id, iova); smmu_flush(smmu); } else { - page = pfn_to_page(pd[pde] & smmu->pfn_mask); + page = as->pts[pde]; } *pagep = page; @@ -550,9 +558,7 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova) unsigned int pde = iova_pd_index(iova); u32 *count = page_address(as->count); u32 *pd = page_address(as->pd); - struct page *page; - - page = pfn_to_page(pd[pde] & smmu->pfn_mask); + struct page *page = as->pts[pde]; /* * When no entries in this page table are used anymore, return the @@ -573,6 +579,7 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova) /* Finally, free the page */ ClearPageReserved(page); __free_page(page); + as->pts[pde] = NULL; } }