From patchwork Tue Jul 7 13:58:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 6732871 Return-Path: X-Original-To: patchwork-linux-spi@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 5A070C05AC for ; Tue, 7 Jul 2015 13:59:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6CB932051F for ; Tue, 7 Jul 2015 13:59:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9CBCD206DD for ; Tue, 7 Jul 2015 13:59:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757568AbbGGN7T (ORCPT ); Tue, 7 Jul 2015 09:59:19 -0400 Received: from mezzanine.sirena.org.uk ([106.187.55.193]:43087 "EHLO mezzanine.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754940AbbGGN7E (ORCPT ); Tue, 7 Jul 2015 09:59:04 -0400 Received: from 234.27.125.91.dyn.plus.net ([91.125.27.234] helo=finisterre) by mezzanine.sirena.org.uk with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from ) id 1ZCTOl-0001Rd-8k; Tue, 07 Jul 2015 13:59:00 +0000 Received: from broonie by finisterre with local (Exim 4.86_RC4) (envelope-from ) id 1ZCTOc-0005ny-Ez; Tue, 07 Jul 2015 14:58:50 +0100 From: Mark Brown To: Andrew Gabbasov , Mark Brown Cc: linux-spi@vger.kernel.org In-Reply-To: <1435679317-13431-1-git-send-email-andrew_gabbasov@mentor.com> Message-Id: Date: Tue, 07 Jul 2015 14:58:50 +0100 X-SA-Exim-Connect-IP: 91.125.27.234 X-SA-Exim-Mail-From: broonie@sirena.org.uk X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Subject: Applied "spi: Fix per-page mapping of unaligned vmalloc-ed buffer" to the spi tree X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on mezzanine.sirena.org.uk) Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The patch spi: Fix per-page mapping of unaligned vmalloc-ed buffer has been applied to the spi tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark From 65598c13fd66c3b5eac16d5b8eacc704aa17ce40 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Tue, 30 Jun 2015 10:48:37 -0500 Subject: [PATCH] spi: Fix per-page mapping of unaligned vmalloc-ed buffer spi_map_buf() processes mapping of vmalloc-ed buffers in a special way, making mapping of every page separately. However, if the buffer is not aligned to page boundary (e.g. sub-array in a vmalloc-ed array), it fills the scatter table with page-size unaligned pieces, that cross page boundaries. This is incorrect and can, for example, cause memory corruption and various crashes when working with ubifs on spi-nor chips (though those drivers are themselves buggy in that they should be providing DMAable memory to the SPI framework). Fix this by using proper scatter table size and intra-page buffer lengths, so that the whole buffer splits into separate scatter table entries on page boundaries. Signed-off-by: Andrew Gabbasov Signed-off-by: Mark Brown --- drivers/spi/spi.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index cf8b91b..27e4f1f1 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -476,21 +476,30 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, enum dma_data_direction dir) { const bool vmalloced_buf = is_vmalloc_addr(buf); - const int desc_len = vmalloced_buf ? PAGE_SIZE : master->max_dma_len; - const int sgs = DIV_ROUND_UP(len, desc_len); + int desc_len; + int sgs; struct page *vm_page; void *sg_buf; size_t min; int i, ret; + if (vmalloced_buf) { + desc_len = PAGE_SIZE; + sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len); + } else { + desc_len = master->max_dma_len; + sgs = DIV_ROUND_UP(len, desc_len); + } + ret = sg_alloc_table(sgt, sgs, GFP_KERNEL); if (ret != 0) return ret; for (i = 0; i < sgs; i++) { - min = min_t(size_t, len, desc_len); if (vmalloced_buf) { + min = min_t(size_t, + len, desc_len - offset_in_page(buf)); vm_page = vmalloc_to_page(buf); if (!vm_page) { sg_free_table(sgt); @@ -499,6 +508,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, sg_set_page(&sgt->sgl[i], vm_page, min, offset_in_page(buf)); } else { + min = min_t(size_t, len, desc_len); sg_buf = buf; sg_set_buf(&sgt->sgl[i], sg_buf, min); }