From patchwork Fri Jan 6 14:45:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikita Yushchenko X-Patchwork-Id: 9501245 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 E38FD606B4 for ; Fri, 6 Jan 2017 14:48:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B3FE8284CC for ; Fri, 6 Jan 2017 14:48:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A8CBD284D2; Fri, 6 Jan 2017 14:48:43 +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=ham 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 8E217284CC for ; Fri, 6 Jan 2017 14:48:42 +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 1cPVot-00032R-0P; Fri, 06 Jan 2017 14:48:39 +0000 Received: from mail-lf0-x233.google.com ([2a00:1450:4010:c07::233]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cPVon-0002rt-Hd for linux-arm-kernel@lists.infradead.org; Fri, 06 Jan 2017 14:48:36 +0000 Received: by mail-lf0-x233.google.com with SMTP id m78so33919185lfg.2 for ; Fri, 06 Jan 2017 06:48:12 -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=hC2RDHHogpmCJnj7FtsdeaDHG5TRD6g4NpKK/TE0ihM=; b=znKJFBga4wXCv7HOuEu9ehnOvSW15hYz2PEFH3QPvZM2oWLvspt93qvirwj0kPnVSX 0glf8x+O6r4HVZEKzFSITpMW0nutNqBPssVBuU8rUAE9S+/T+7PC/Q81gZRZ+IeP4XI7 +cEx2FHFkiYSdZ3uDIFLrxCYeclfftpW/XG3W8S0a/Yqi0EmzYYf5aWX07FKjA3amsPW 4R2rPpHWPxa+sc0O9YRpBVlO90PHnLm0RtFYVUjwJsj1FdmgRdcnXXpUEZFtVI1kHpRA pvjMUrZsfMbyEEhaMt6alsqxrpAfPg3UGb8FZHpgKx0ngDguFNVGYaHHFQaucGxyTGLn VY1g== 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=hC2RDHHogpmCJnj7FtsdeaDHG5TRD6g4NpKK/TE0ihM=; b=K3bmbz/YmdrD8FDoMi5sZ4Hc4YOqirO/Ogv8dxec8Q5B0BAG/mlNBZlrdyRT0AFn7J czeo2LzyKLgF7bC6IBpRhG7/JlaaZN6sk1Dpa9xFBlL1xBeJqKCxWNxaUCb3xEkon7nX NCxMedTR+7+Z/K+gth0m15PD36oJV45Hl8d17w/Rgu+6guifOyhy50SI4g06c1KG4l40 o0NhU4XfsKFDDVvfmP9e3BrChirFA3W+vQI3IxowQypQXJtlqpKXLKORPQbsVmaMyB9p NVsBXMOWU13OFiKrSSCo42DFPwp803StnXxJIfhNMPfyOV0/Dn2Fdpy8mSwZZOBUozAg 1HOg== X-Gm-Message-State: AIkVDXKaiJGd9bpabE80d+UDarstg4EVuKhd2hVKXSSJNdZ8HOWixHWd/RoWnU42EKCeMQ== X-Received: by 10.46.71.204 with SMTP id u195mr3458724lja.71.1483714091247; Fri, 06 Jan 2017 06:48:11 -0800 (PST) Received: from hugenb.home (nikaet.starlink.ru. [94.141.168.29]) by smtp.gmail.com with ESMTPSA id n124sm17168332lfn.5.2017.01.06.06.48.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Jan 2017 06:48:10 -0800 (PST) From: Nikita Yushchenko To: Arnd Bergmann Subject: [PATCH] arm64: do not set dma masks that device connection can't handle Date: Fri, 6 Jan 2017 17:45:11 +0300 Message-Id: <1483713911-2079-1-git-send-email-nikita.yoush@cogentembedded.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <9a03c05d-ad4c-0547-d1fe-01edb8b082d6@cogentembedded.com> References: <9a03c05d-ad4c-0547-d1fe-01edb8b082d6@cogentembedded.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170106_064834_020392_AC82F452 X-CRM114-Status: GOOD ( 18.38 ) 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 , Catalin Marinas , Will Deacon , linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Simon Horman , Bjorn Helgaas , artemi.ivanov@cogentembedded.com, 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 It is possible that device is capable of 64-bit DMA addresses, and device driver tries to set wide DMA mask, but bridge or bus used to connect device to the system can't handle wide addresses. With swiotlb, memory above 4G still can be used by drivers for streaming DMA, but *dev->mask and dev->dma_coherent_mask must still keep values that hardware handles physically. This patch enforces that. Based on original version by Arnd Bergmann , extended with coherent mask hadnling. Signed-off-by: Nikita Yushchenko CC: Arnd Bergmann --- ... now with initially missed change in arch_setup_dma_ops() ... arch/arm64/Kconfig | 3 +++ arch/arm64/include/asm/device.h | 1 + arch/arm64/mm/dma-mapping.c | 52 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 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/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 290a84f..09c7900 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -352,6 +352,31 @@ static int __swiotlb_dma_supported(struct device *hwdev, u64 mask) return 1; } +static int __swiotlb_set_dma_mask(struct device *dev, u64 mask) +{ + /* device is not DMA capable */ + if (!dev->dma_mask) + return -EIO; + + /* mask is below swiotlb bounce buffer, so fail */ + if (!swiotlb_dma_supported(dev, mask)) + return -EIO; + + /* + * because of the swiotlb, we can return success for + * larger masks, but need to ensure that bounce buffers + * are used above parent_dma_mask, so set that as + * the effective mask. + */ + if (mask > dev->archdata.parent_dma_mask) + mask = dev->archdata.parent_dma_mask; + + + *dev->dma_mask = mask; + + return 0; +} + static struct dma_map_ops swiotlb_dma_ops = { .alloc = __dma_alloc, .free = __dma_free, @@ -367,8 +392,23 @@ static struct dma_map_ops swiotlb_dma_ops = { .sync_sg_for_device = __swiotlb_sync_sg_for_device, .dma_supported = __swiotlb_dma_supported, .mapping_error = swiotlb_dma_mapping_error, + .set_dma_mask = __swiotlb_set_dma_mask, }; +int dma_set_coherent_mask(struct device *dev, u64 mask) +{ + if (!dma_supported(dev, mask)) + return -EIO; + + if (get_dma_ops(dev) == &swiotlb_dma_ops && + mask > dev->archdata.parent_dma_mask) + mask = dev->archdata.parent_dma_mask; + + dev->coherent_dma_mask = mask; + return 0; +} +EXPORT_SYMBOL(dma_set_coherent_mask); + static int __init atomic_pool_init(void) { pgprot_t prot = __pgprot(PROT_NORMAL_NC); @@ -957,6 +997,18 @@ 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; + /* + * we don't yet support buses that have a non-zero mapping. + * Let's hope we won't need it + */ + WARN_ON(dma_base != 0); + + /* + * Whatever the parent bus can set. A device must not set + * a DMA mask larger than this. + */ + dev->archdata.parent_dma_mask = size; + dev->archdata.dma_coherent = coherent; __iommu_setup_dma_ops(dev, dma_base, size, iommu); }