From patchwork Fri Sep 25 12:15:46 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 7264051 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1DED3BEEC1 for ; Fri, 25 Sep 2015 12:18:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 237C920AFD for ; Fri, 25 Sep 2015 12:18:49 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7414420B00 for ; Fri, 25 Sep 2015 12:18:47 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZfRvw-0004Nc-FK; Fri, 25 Sep 2015 12:17:00 +0000 Received: from eu-smtp-delivery-143.mimecast.com ([146.101.78.143]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZfRvH-0003uM-FV for linux-arm-kernel@lists.infradead.org; Fri, 25 Sep 2015 12:16:22 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-3-Tv8lptWVTiqvGTysBBnFBg-9; Fri, 25 Sep 2015 13:15:57 +0100 Received: from e104324-lin.cambridge.arm.com ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 25 Sep 2015 13:15:54 +0100 From: Robin Murphy To: akpm@linux-foundation.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] dma-debug: Allow poisoning nonzero allocations Date: Fri, 25 Sep 2015 13:15:46 +0100 Message-Id: <0405c6131def5aa179ff4ba5d4201ebde89cede3.1443178314.git.robin.murphy@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: X-OriginalArrivalTime: 25 Sep 2015 12:15:54.0193 (UTC) FILETIME=[ECF7EC10:01D0F78B] X-MC-Unique: Tv8lptWVTiqvGTysBBnFBg-9 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150925_051619_887523_56FA7C1E X-CRM114-Status: UNSURE ( 9.95 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -4.2 (----) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arch@vger.kernel.org, arnd@arndb.de, linux-mm@kvack.org, sakari.ailus@iki.fi, sumit.semwal@linaro.org, linux-arm-kernel@lists.infradead.org, m.szyprowski@samsung.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since some dma_alloc_coherent implementations return a zeroed buffer regardless of whether __GFP_ZERO is passed, there exist drivers which are implicitly dependent on this and pass otherwise uninitialised buffers to hardware. This can lead to subtle and awkward-to-debug issues using those drivers on different platforms, where nonzero uninitialised junk may for instance occasionally look like a valid command which causes the hardware to start misbehaving. To help with debugging such issues, add the option to make uninitialised buffers much more obvious. Signed-off-by: Robin Murphy --- include/asm-generic/dma-mapping-common.h | 2 +- include/linux/dma-debug.h | 6 ++++-- include/linux/poison.h | 3 +++ lib/Kconfig.debug | 10 ++++++++++ lib/dma-debug.c | 6 +++++- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/include/asm-generic/dma-mapping-common.h b/include/asm-generic/dma-mapping-common.h index b1bc954..0f3e16b 100644 --- a/include/asm-generic/dma-mapping-common.h +++ b/include/asm-generic/dma-mapping-common.h @@ -260,7 +260,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size, return NULL; cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs); - debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); + debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr, flag); return cpu_addr; } diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h index fe8cb61..e5f539d 100644 --- a/include/linux/dma-debug.h +++ b/include/linux/dma-debug.h @@ -51,7 +51,8 @@ extern void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems, int dir); extern void debug_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t dma_addr, void *virt); + dma_addr_t dma_addr, void *virt, + gfp_t flags); extern void debug_dma_free_coherent(struct device *dev, size_t size, void *virt, dma_addr_t addr); @@ -132,7 +133,8 @@ static inline void debug_dma_unmap_sg(struct device *dev, } static inline void debug_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t dma_addr, void *virt) + dma_addr_t dma_addr, void *virt, + gfp_t flags) { } diff --git a/include/linux/poison.h b/include/linux/poison.h index 317e16d..174104e 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -73,6 +73,9 @@ #define MUTEX_DEBUG_INIT 0x11 #define MUTEX_DEBUG_FREE 0x22 +/********** lib/dma_debug.c **********/ +#define DMA_ALLOC_POISON 0xee + /********** lib/flex_array.c **********/ #define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */ diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ab76b99..f2da7a1 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1752,6 +1752,16 @@ config DMA_API_DEBUG If unsure, say N. +config DMA_API_DEBUG_POISON + bool "Poison coherent DMA buffers" + depends on DMA_API_DEBUG && EXPERT + help + Poison DMA buffers returned by dma_alloc_coherent unless __GFP_ZERO + is explicitly specified, to catch drivers depending on zeroed buffers + without passing the correct flags. + + Only say Y if you're prepared for almost everything to break. + config TEST_LKM tristate "Test module loading with 'hello world' module" default n diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 908fb35..40514ed 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -1447,7 +1448,7 @@ void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, EXPORT_SYMBOL(debug_dma_unmap_sg); void debug_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t dma_addr, void *virt) + dma_addr_t dma_addr, void *virt, gfp_t flags) { struct dma_debug_entry *entry; @@ -1457,6 +1458,9 @@ void debug_dma_alloc_coherent(struct device *dev, size_t size, if (unlikely(virt == NULL)) return; + if (IS_ENABLED(CONFIG_DMA_API_DEBUG_POISON) && !(flags & __GFP_ZERO)) + memset(virt, DMA_ALLOC_POISON, size); + entry = dma_entry_alloc(); if (!entry) return;