From patchwork Wed Jan 11 18:31:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikita Yushchenko X-Patchwork-Id: 9511015 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 311F26075C for ; Wed, 11 Jan 2017 18:33:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 19ABE28662 for ; Wed, 11 Jan 2017 18:33:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E5A428667; Wed, 11 Jan 2017 18:33:09 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9613328662 for ; Wed, 11 Jan 2017 18:33:08 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cRNhp-0002sI-KZ; Wed, 11 Jan 2017 18:33:05 +0000 Received: from mail-lf0-x229.google.com ([2a00:1450:4010:c07::229]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cRNhT-0002Gv-QY for linux-arm-kernel@lists.infradead.org; Wed, 11 Jan 2017 18:32:45 +0000 Received: by mail-lf0-x229.google.com with SMTP id m78so121360092lfg.2 for ; Wed, 11 Jan 2017 10:32:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cogentembedded-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2JPQnF0hWQbAsnKDQ0sHrlzZ1Z742Gu139QZWz2AmIU=; b=DXAESSjMhz9Y/9dulw+J6jdMJJcTL4niqgG3zYiX+XN/Mog1Nst7qeVCorsifq/tYR 8brbsWwDBeQPc8Gs5AttDV+dK/FmEp9edLu/d4sW+uKgvT6PxLu+8tCjinmbX7FyAEsm gncvRmy3Cc5bvYGKkp2vsNiEWUBzJLieLkNDA/ggpnZvsM1wwt4YF5Evz1Ik7wGPA/7O HRy5DxQRuCkcbiKDMg2HCvnK9DsTsxy2mZCqDOMEXK7zpPGtPErMcDstcN074KkzBMBS 6+9cfTtqWrpsn8eGAmAG+EfXuw1d6c9tIzGhcaf9kpg2pcKrhZRGVNffYIaWbOIMZ5Hl fvFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=2JPQnF0hWQbAsnKDQ0sHrlzZ1Z742Gu139QZWz2AmIU=; b=qEuVsYlWVw2iqMmQhFXk15RiKDmhe+S/uKLayLHiqT6SPO80yR3+7cB8NkzDTt790g C8xwzg0X77ph870QpamMW+264ITGsoFAMF1u9YqdV+s9t3WEGVfNIzO3EcBQs7TYXtxo W9D+2ltjzxQvTsriIMSMecAZbVG2J2IE1Wg8QLn2HhfYL74WofvaKw0+TdXZJz1day3v 5NrlFfC6XpLNG014mv44gU52NpW0b2EVE/XH+5zUCNPOlmOSKKdO4lVtKHrlLIDR40CQ 2ZgXeI5W+wQOv9jettHBezbXbdqrMr8lm29nBwE92RHNE5PH5a8Qh88ejyfGQBwt3AKT EIPg== X-Gm-Message-State: AIkVDXI9cM5xcBzG39bk7L2K5osld3CtevwD2ENWAXHHLVmfVAHnRE2BFp/KQD6s7CRQwQ== X-Received: by 10.25.20.66 with SMTP id k63mr3870691lfi.111.1484159541509; Wed, 11 Jan 2017 10:32:21 -0800 (PST) Received: from hugenb.home (nikaet.starlink.ru. [94.141.168.29]) by smtp.gmail.com with ESMTPSA id s20sm361640lfe.41.2017.01.11.10.32.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 11 Jan 2017 10:32:20 -0800 (PST) From: Nikita Yushchenko To: Robin Murphy , Will Deacon , Arnd Bergmann Subject: [PATCH 2/2] arm64: avoid increasing DMA masks above what hardware supports Date: Wed, 11 Jan 2017 21:31:52 +0300 Message-Id: <1484159512-28515-3-git-send-email-nikita.yoush@cogentembedded.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1484159512-28515-1-git-send-email-nikita.yoush@cogentembedded.com> References: <1484159512-28515-1-git-send-email-nikita.yoush@cogentembedded.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170111_103244_076281_1A636EDE X-CRM114-Status: GOOD ( 14.93 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nikita Yushchenko , fkan@apm.com, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Simon Horman , Bjorn Helgaas , Artemi Ivanov , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP There are cases when device supports wide DMA addresses wider than device's connection supports. In this case driver sets DMA mask based on knowledge of device capabilities. That must succeed to allow drivers to initialize. However, swiotlb or iommu still need knowledge about actual device capabilities. To avoid breakage, actual mask must not be set wider than device connection allows. Signed-off-by: Nikita Yushchenko CC: Arnd Bergmann CC: Robin Murphy CC: Will Deacon --- arch/arm64/Kconfig | 3 +++ arch/arm64/include/asm/device.h | 1 + arch/arm64/include/asm/dma-mapping.h | 3 +++ arch/arm64/mm/dma-mapping.c | 40 ++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1117421..afb2c08 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -216,6 +216,9 @@ config NEED_DMA_MAP_STATE config NEED_SG_DMA_LENGTH def_bool y +config ARCH_HAS_DMA_SET_COHERENT_MASK + def_bool y + config SMP def_bool y diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h index 243ef25..a57e7bb 100644 --- a/arch/arm64/include/asm/device.h +++ b/arch/arm64/include/asm/device.h @@ -22,6 +22,7 @@ struct dev_archdata { void *iommu; /* private IOMMU data */ #endif bool dma_coherent; + u64 parent_dma_mask; }; struct pdev_archdata { diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h index ae1c23f..46b53e6 100644 --- a/arch/arm64/include/asm/dma-mapping.h +++ b/arch/arm64/include/asm/dma-mapping.h @@ -52,6 +52,9 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, bool coherent); #define arch_setup_dma_ops arch_setup_dma_ops +#define HAVE_ARCH_DMA_SET_MASK 1 +extern int dma_set_mask(struct device *dev, u64 dma_mask); + #ifdef CONFIG_IOMMU_DMA void arch_teardown_dma_ops(struct device *dev); #define arch_teardown_dma_ops arch_teardown_dma_ops diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index ea295f1..31b96fd 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -203,6 +203,37 @@ static void __dma_free(struct device *dev, size_t size, __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs); } +int dma_set_mask(struct device *dev, u64 dma_mask) +{ + const struct dma_map_ops *ops = get_dma_ops(dev); + + if (mask > dev->archdata.parent_dma_mask) + mask = dev->archdata.parent_dma_mask; + + if (ops->set_dma_mask) + return ops->set_dma_mask(dev, mask); + + if (!dev->dma_mask || !dma_supported(dev, mask)) + return -EIO; + + *dev->dma_mask = mask; + return 0; +} +EXPORT_SYMBOL(dma_set_mask); + +int dma_set_coherent_mask(struct device *dev, u64 mask) +{ + if (mask > dev->archdata.parent_dma_mask) + mask = dev->archdata.parent_dma_mask; + + if (!dma_supported(dev, mask)) + return -EIO; + + dev->coherent_dma_mask = mask; + return 0; +} +EXPORT_SYMBOL(dma_set_coherent_mask); + static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, @@ -959,6 +990,15 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, if (!dev->archdata.dma_ops) dev->archdata.dma_ops = &swiotlb_dma_ops; + /* + * Whatever the parent bus can set. A device must not set + * a DMA mask larger than this. + */ + if (enforce_range) + dev->archdata.parent_dma_mask = size - 1; + else + dev->archdata.parent_dma_mask = DMA_BIT_MASK(64); + dev->archdata.dma_coherent = coherent; __iommu_setup_dma_ops(dev, dma_base, size, iommu); }