From patchwork Fri Nov 11 14:22:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Burton X-Patchwork-Id: 9423097 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 5DA5060233 for ; Fri, 11 Nov 2016 14:23:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E52B24EE5 for ; Fri, 11 Nov 2016 14:23:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 430CB2921C; Fri, 11 Nov 2016 14:23:01 +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,RCVD_IN_DNSWL_HI autolearn=ham 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 9E6CD24EE5 for ; Fri, 11 Nov 2016 14:23:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752395AbcKKOW7 (ORCPT ); Fri, 11 Nov 2016 09:22:59 -0500 Received: from mailapp01.imgtec.com ([195.59.15.196]:40862 "EHLO mailapp01.imgtec.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751821AbcKKOW7 (ORCPT ); Fri, 11 Nov 2016 09:22:59 -0500 Received: from HHMAIL01.hh.imgtec.org (unknown [10.100.10.19]) by Forcepoint Email with ESMTPS id 5B25319DC958D; Fri, 11 Nov 2016 14:22:53 +0000 (GMT) Received: from localhost (10.100.200.224) by HHMAIL01.hh.imgtec.org (10.100.10.21) with Microsoft SMTP Server (TLS) id 14.3.294.0; Fri, 11 Nov 2016 14:22:56 +0000 From: Paul Burton To: CC: Paul Burton , Ulf Hansson Subject: [PATCH] mmc: sd: Meet alignment requirements for raw_ssr DMA Date: Fri, 11 Nov 2016 14:22:36 +0000 Message-ID: <20161111142236.8270-1-paul.burton@imgtec.com> X-Mailer: git-send-email 2.10.2 MIME-Version: 1.0 X-Originating-IP: [10.100.200.224] Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The mmc_read_ssr() function results in DMA to the raw_ssr member of struct mmc_card, which is not guaranteed to be cache line aligned & thus might not meet the requirements set out in Documentation/DMA-API.txt: Warnings: Memory coherency operates at a granularity called the cache line width. In order for memory mapped by this API to operate correctly, the mapped region must begin exactly on a cache line boundary and end exactly on one (to prevent two separately mapped regions from sharing a single cache line). Since the cache line size may not be known at compile time, the API will not enforce this requirement. Therefore, it is recommended that driver writers who don't take special care to determine the cache line size at run time only map virtual regions that begin and end on page boundaries (which are guaranteed also to be cache line boundaries). On some systems where DMA is non-coherent this can lead to us losing data that shares cache lines with the raw_ssr array. Fix this by kmalloc'ing a temporary buffer to perform DMA into. kmalloc will ensure the buffer is suitably aligned, allowing the DMA to be performed without any loss of data. Signed-off-by: Paul Burton Cc: Ulf Hansson Cc: linux-mmc@vger.kernel.org --- drivers/mmc/core/sd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 73c762a..f6f40a1 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -223,6 +223,7 @@ static int mmc_decode_scr(struct mmc_card *card) static int mmc_read_ssr(struct mmc_card *card) { unsigned int au, es, et, eo; + u32 *raw_ssr; int i; if (!(card->csd.cmdclass & CCC_APP_SPEC)) { @@ -231,14 +232,21 @@ static int mmc_read_ssr(struct mmc_card *card) return 0; } - if (mmc_app_sd_status(card, card->raw_ssr)) { + raw_ssr = kmalloc(sizeof(card->raw_ssr), GFP_KERNEL); + if (!raw_ssr) + return -ENOMEM; + + if (mmc_app_sd_status(card, raw_ssr)) { pr_warn("%s: problem reading SD Status register\n", mmc_hostname(card->host)); + kfree(raw_ssr); return 0; } for (i = 0; i < 16; i++) - card->raw_ssr[i] = be32_to_cpu(card->raw_ssr[i]); + card->raw_ssr[i] = be32_to_cpu(raw_ssr[i]); + + kfree(raw_ssr); /* * UNSTUFF_BITS only works with four u32s so we have to offset the