Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935974AbcLOQUQ (ORCPT ); Thu, 15 Dec 2016 11:20:16 -0500 Received: from mail-wm0-f53.google.com ([74.125.82.53]:33057 "EHLO mail-wm0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755135AbcLOQUP (ORCPT ); Thu, 15 Dec 2016 11:20:15 -0500 From: Nikita Yushchenko Subject: arm64: mm: bug around swiotlb_dma_ops X-Enigmail-Draft-Status: N1110 To: Catalin Marinas , Will Deacon , Simon Horman , Magnus Damm , Vladimir Barinov , Artemi Ivanov Cc: "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" Message-ID: <8862fe21-0a82-a09a-c1cb-aa79d46179ec@cogentembedded.com> Date: Thu, 15 Dec 2016 19:20:11 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1281 Lines: 38 Hi. Per Documentation/DMA-API-HOWTO.txt, driver of device capable of 64-bit DMA addressing, should call dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) and if that succeeds, assume that 64-bit DMA addressing is available. This behaves incorrectly on arm64 system (Renesas r8a7795-h3ulcb) here. - Device (NVME SSD) has it's dev->archdata.dma_ops set to swiotlb_dma_ops. - swiotlb_dma_ops.dma_supported is set to swiotlb_dma_supported(): int swiotlb_dma_supported(struct device *hwdev, u64 mask) { return phys_to_dma(hwdev, io_tlb_end - 1) <= mask; } this definitely returns true for mask=DMA_BIT_MASK(64) since that is maximum possible 64-bit value. - Thus device dma_mask is unconditionally updated, and dma_set_mask_and_coherent() succeeds. - Later, __swiotlb_map_page() / __swiotlb_map_sg_attr() will consult this updated mask, and return high addresses as valid DMA addresses. Thus recommended dma_set_mask_and_coherent() call, instead of checking if platform supports 64-bit DMA addressing, unconditionally enables 64-bit DMA addressing. In case of device actually can't do DMA to 64-bit addresses (e.g. because of limitations in PCIe controller), this breaks things. This is exactly what happens here. Not sure what is proper fix for this though. Nikita