From patchwork Fri Jan 6 14:38:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikita Yushchenko X-Patchwork-Id: 9501225 X-Patchwork-Delegate: horms@verge.net.au 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 24045606E1 for ; Fri, 6 Jan 2017 14:39:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E866B2840A for ; Fri, 6 Jan 2017 14:39:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCE1C284C8; Fri, 6 Jan 2017 14:39:21 +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 8B9CF28473 for ; Fri, 6 Jan 2017 14:39:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757725AbdAFOjS (ORCPT ); Fri, 6 Jan 2017 09:39:18 -0500 Received: from mail-lf0-f46.google.com ([209.85.215.46]:35544 "EHLO mail-lf0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753630AbdAFOis (ORCPT ); Fri, 6 Jan 2017 09:38:48 -0500 Received: by mail-lf0-f46.google.com with SMTP id m78so33769875lfg.2 for ; Fri, 06 Jan 2017 06:38:47 -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=9V5X+R3U5lreAX3OFyPrsE5JjCOupL7Mp4yWcubDhxU=; b=VP16GRRvx2yAfevMfjKqg0422D+wKtrwpnVaoYuZuvlggXN00r56D8rKzy71bR0+X/ cGVco6uUM1xjX+glgwzUL6nX4ufjUXzJkrv7REqz+IKL7jhfQUXhlPdbO7Cmog5W9Q6b py1sAQ3ccuBKwcx1mkNWm+psE+/IRqqFQ3ZnU8WM+uOaxgpmyDB1B/QM7ErGN/GkF8f+ y0M7TqTquznOs2dIL2i388DlwX98WCNtlzKINbnpgG9DYZGoK5mEMt2nkTFy/ls6GNeY qYpi4Ghxa+m1awQKr7TUc6oIhfpddr+qwCa0ccLzTg3gDl0/Y8yS+3gRHCiPQHIYxE07 xF8g== 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=9V5X+R3U5lreAX3OFyPrsE5JjCOupL7Mp4yWcubDhxU=; b=YjPR/FAQrAWHBgcqueg6vPuNJYJ70H+70RCaRG008pmxeINDtNam5veqLlx3mpvcon uXb88uMTMwSBR8RpmAP5NWJ+Mp4SOrqtzud/UmOjE4K3XO8S3vD1mAoDkYqb52cdikaP Kg3knIud3Nb3UwqPU5vkI4lxwQn7/oI3PDeW/7P/pKdEIkwwaKEkgH0jgfiAk/INYdU4 h7yeVj2sa41Zl/ssU2PT0LS7RTC42skoDd5YPOHVSDnxQnpHRNJa6K94xlhLNHWJTnz0 pJV053cpRO8BE/tYqxMvtJHXhvP8rHC3lsxjhJsL6GIVHt0KRjzr8R3WguKF8hG37BV4 40gQ== X-Gm-Message-State: AIkVDXJ9B0q71X47nQmosIz5glGSiNYTPHKeqkVHDc1MowCvNkOZr6xxoDGtxMIiA0gzeQ== X-Received: by 10.25.204.216 with SMTP id c207mr8114360lfg.107.1483713526482; Fri, 06 Jan 2017 06:38:46 -0800 (PST) Received: from hugenb.home (nikaet.starlink.ru. [94.141.168.29]) by smtp.gmail.com with ESMTPSA id e6sm12067055lji.34.2017.01.06.06.38.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Jan 2017 06:38:45 -0800 (PST) From: Nikita Yushchenko To: Arnd Bergmann Cc: linux-arm-kernel@lists.infradead.org, Will Deacon , Catalin Marinas , linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Simon Horman , Bjorn Helgaas , artemi.ivanov@cogentembedded.com, Nikita Yushchenko Subject: [PATCH] arm64: do not set dma masks that device connection can't handle Date: Fri, 6 Jan 2017 17:38:35 +0300 Message-Id: <1483713515-1945-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> 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 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 --- arch/arm64/Kconfig | 3 +++ arch/arm64/include/asm/device.h | 1 + arch/arm64/mm/dma-mapping.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 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..be3632e 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);