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: 9511007 X-Patchwork-Delegate: geert@linux-m68k.org 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 9BBCC6075C for ; Wed, 11 Jan 2017 18:32:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 826F928666 for ; Wed, 11 Jan 2017 18:32:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 744B528667; Wed, 11 Jan 2017 18:32:44 +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=-6.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D4BA428662 for ; Wed, 11 Jan 2017 18:32:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936743AbdAKScZ (ORCPT ); Wed, 11 Jan 2017 13:32:25 -0500 Received: from mail-lf0-f54.google.com ([209.85.215.54]:34484 "EHLO mail-lf0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1764507AbdAKScX (ORCPT ); Wed, 11 Jan 2017 13:32:23 -0500 Received: by mail-lf0-f54.google.com with SMTP id v186so88426417lfa.1 for ; Wed, 11 Jan 2017 10:32:22 -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=Ep/najX09MnHNueNpqGN2CDWUVYXA180FFcixfQ3rAPYIyOt0UXQYXtRFUpqfh72i4 wd8viOs1s2uYkGfQh8Sai7o8RPpZwmm5ZCgzKkh77cdG01o4XBJt3+LGGXfB/YHR8MSy BhiyNRVtY7yzRZQvQ6ftzJXKrLXQqYwbA/w23vYm7U06u+m7i8dEqnSd7IVrkZtHkx65 kWxIEGOsM8758j2YTh/kIC/lum3o1M0CCAGf08fvJnnG4Jj1Lgg4OX5W2s6wYR2ez/70 2UHfn+TvjJgoWcUEjlo3azGqTM0I2ql8XyKff5CJ5SsJIPcAui6ij9W9ZoAWGxzwudcE vXcA== X-Gm-Message-State: AIkVDXK7lsD6wcaJz7TqpWUt6jmRiR0aak01I3++UlP9Pvblsvq4+KL1ij+Xajqzx1c+0g== 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 Cc: linux-arm-kernel@lists.infradead.org, linux-renesas-soc@vger.kernel.org, Simon Horman , Bjorn Helgaas , fkan@apm.com, linux-kernel@vger.kernel.org, Artemi Ivanov , Nikita Yushchenko 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> Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.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); }