From patchwork Tue Mar 8 09:22:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 63659 Delivered-To: patch@linaro.org Received: by 10.112.199.169 with SMTP id jl9csp1917653lbc; Tue, 8 Mar 2016 01:22:48 -0800 (PST) X-Received: by 10.98.80.150 with SMTP id g22mr40403186pfj.132.1457428967998; Tue, 08 Mar 2016 01:22:47 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id kg1si3526467pad.81.2016.03.08.01.22.47; Tue, 08 Mar 2016 01:22:47 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dkim=pass header.i=@linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932719AbcCHJWi (ORCPT + 30 others); Tue, 8 Mar 2016 04:22:38 -0500 Received: from mail-pa0-f48.google.com ([209.85.220.48]:33888 "EHLO mail-pa0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932656AbcCHJWa (ORCPT ); Tue, 8 Mar 2016 04:22:30 -0500 Received: by mail-pa0-f48.google.com with SMTP id fy10so8734612pac.1 for ; Tue, 08 Mar 2016 01:22:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7jlqgOSi7NVsv2LfAv5sWeRBrOaqzAKqqCLFqrmKS7U=; b=WSzqjCd6dtE7v/a/gTyClq9bXqkhdZ87g+JHWtVNn3L2TA/ihmTgv6fWhOl5lFPYnn lwF3unk5VPnv91evF2Ukvl2YbIGTyrjlpCeU+U0qnR+Izinj06Co1B/uG+krqU36wgI4 BEMrUfxTLCUEaC/ES+mNRHfHMT0GB4KqJyzmM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7jlqgOSi7NVsv2LfAv5sWeRBrOaqzAKqqCLFqrmKS7U=; b=c5gAsCbL5exliwJ8xEqTK/AZMhjIY1H5KB0/wyCv3pCL7iqX6JMu9ulICi18wiHL1v 5jq8j+6hhTFiC5guA/ATQSlexiFPq2zCgq9K0QRAnnLttVvr8RddLhcGlaCymNBIIQKF rOE7Jw4vlAz2uY3Uif/fxUMrGx4X+/Eb9QEwjRGhaEAhGXQasHJwZeAUGT2Nwga8I3OW lETj0xdm7VdK7Sw2EfVCg2K9o55lJ0GUkiTXUyTWV16ks5yMajDqqOFIR1vFhEg3Hzys aNdvbmy8InN4b0EsVbnd9G0OcvdnHM9KCTUNzPeTUIzhsEwwNPQAcsa+A9QVdxWIuIMo UO3A== X-Gm-Message-State: AD7BkJLfIum36ur3EXRlgx91HKUnVXQgrob5AaTIPijl/y9DpFobNm9tgDK7IdIFTRMN0/jb X-Received: by 10.66.234.104 with SMTP id ud8mr40361648pac.143.1457428949180; Tue, 08 Mar 2016 01:22:29 -0800 (PST) Received: from localhost.localdomain (110-170-137-3.static.asianet.co.th. [110.170.137.3]) by smtp.gmail.com with ESMTPSA id i11sm3330224pfi.55.2016.03.08.01.22.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 08 Mar 2016 01:22:28 -0800 (PST) From: Stephen Boyd To: linux-kernel@vger.kernel.org Cc: linux-arm@lists.infradead.org, Greg Kroah-Hartman , Mimi Zohar , Andrew Morton , Mark Brown , Laura Abbott , Robin Murphy , Laura Abbott , Arnd Bergmann , Marek Szyprowski , Catalin Marinas , Will Deacon Subject: [PATCH 1/4] ARM64: dma: Add support for NO_KERNEL_MAPPING attribute Date: Tue, 8 Mar 2016 16:22:16 +0700 Message-Id: <1457428939-26659-2-git-send-email-stephen.boyd@linaro.org> X-Mailer: git-send-email 2.7.0.25.gfc10eb5 In-Reply-To: <1457428939-26659-1-git-send-email-stephen.boyd@linaro.org> References: <1457428939-26659-1-git-send-email-stephen.boyd@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Both the IOMMU and non-IOMMU allocations don't respect the NO_KERNEL_MAPPING attribute, therefore drivers can't save virtual address space and time spent mapping large buffers that are intended only for userspace. Plumb this attribute into the code for both types of DMA ops. Cc: Robin Murphy Cc: Laura Abbott Cc: Arnd Bergmann Cc: Marek Szyprowski Cc: Catalin Marinas Cc: Will Deacon Signed-off-by: Stephen Boyd --- arch/arm64/mm/dma-mapping.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) -- 2.7.0.25.gfc10eb5 diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 331c4ca6205c..06a593653f23 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -169,6 +169,9 @@ static void *__dma_alloc(struct device *dev, size_t size, /* create a coherent mapping */ page = virt_to_page(ptr); + if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) + return page; + coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP, prot, NULL); if (!coherent_ptr) @@ -194,7 +197,8 @@ static void __dma_free(struct device *dev, size_t size, if (!is_device_dma_coherent(dev)) { if (__free_from_pool(vaddr, size)) return; - vunmap(vaddr); + if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) + vunmap(vaddr); } __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs); } @@ -567,6 +571,9 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size, if (!pages) return NULL; + if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) + return pages; + addr = dma_common_pages_remap(pages, size, VM_USERMAP, prot, __builtin_return_address(0)); if (!addr) @@ -624,18 +631,32 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr, if (WARN_ON(!area || !area->pages)) return; iommu_dma_free(dev, area->pages, iosize, &handle); - dma_common_free_remap(cpu_addr, size, VM_USERMAP); + if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) + dma_common_free_remap(cpu_addr, size, VM_USERMAP); } else { iommu_dma_unmap_page(dev, handle, iosize, 0, NULL); __free_pages(virt_to_page(cpu_addr), get_order(size)); } } +static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs) +{ + struct vm_struct *area; + + if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) + return cpu_addr; + + area = find_vm_area(cpu_addr); + if (area) + return area->pages; + return NULL; +} + static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) { - struct vm_struct *area; + struct page **pages; int ret; vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, @@ -644,11 +665,11 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) return ret; - area = find_vm_area(cpu_addr); - if (WARN_ON(!area || !area->pages)) + pages = __iommu_get_pages(cpu_addr, attrs); + if (WARN_ON(!pages)) return -ENXIO; - return iommu_dma_mmap(area->pages, size, vma); + return iommu_dma_mmap(pages, size, vma); } static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt, @@ -656,12 +677,12 @@ static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt, size_t size, struct dma_attrs *attrs) { unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; - struct vm_struct *area = find_vm_area(cpu_addr); + struct page **pages = __iommu_get_pages(cpu_addr, attrs); - if (WARN_ON(!area || !area->pages)) + if (WARN_ON(!pages)) return -ENXIO; - return sg_alloc_table_from_pages(sgt, area->pages, count, 0, size, + return sg_alloc_table_from_pages(sgt, pages, count, 0, size, GFP_KERNEL); }