Received: by 10.213.65.68 with SMTP id h4csp1863057imn; Mon, 19 Mar 2018 15:35:46 -0700 (PDT) X-Google-Smtp-Source: AG47ELuzjyXuVrlypbfuD++MedSNO4E6+xftYgu5vMLWe2AAkB9u3Czni/YhX5s2+ldRUNLHB8KM X-Received: by 2002:a17:902:bd94:: with SMTP id q20-v6mr14234652pls.364.1521498946793; Mon, 19 Mar 2018 15:35:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521498946; cv=none; d=google.com; s=arc-20160816; b=ywksDVO9mybpfChJL7bmqpm4PPaoYXaj1w3a4+jHSSkCetBkaFV+yjZ40ub87atWrn PNheMfDlZkgNZmEkV5RT1+XKOVV39EKtbrPof5ehRc/QGMNNBOf1ENsb/Z7arsWQsBFV +aGe7ovV2MuGDHDRfPsh9QLT0APbpRAi688l49REsMGV6k0RHWjSKnchnr3ufqsaN7rw FNAEXkPjL2KeH4+yeBqjauQJ0JhQegoXN43+fqdPXsG0jdINa8aGqDRvAYQ139M4bBaw mi8maFqRiKOZcoWyDAHfQNblODYU42i7+cpNUJ6PxK65o5hDUKH/nE4Soqe//ZNQkpS6 chPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature :arc-authentication-results; bh=YV7AO6YjRpHZ3TLM7Nsy4+A27rJytMvIcmhejcaUl+Q=; b=vlNEGG3tu+qLkJXe+BzvEw0376ARWg4Nuy5jdEJGo4z1sGGP9M0LECoa+mH4FTrKLs e7/3bm8V4olqclMMm/1s4vIxLclf2R2k5W9tAFRA3v6PeDqpMwjyxnkzP34ozGxirqys MqAw/9KEWCNbfgSCyS/Z53roBliK+014My4NV8Dk1jLjT+fUrFSXvFk6yb80gxK3LdpV +aOJt4HoE1FzZjk3VyBqhJ9Ee3OyunSWEuLv5pcmULrlP24vNDMbJnVXP8d+q5pHTeNV 0X0vPq40kJRaGTrWy0UnMUXIN1vBGkEDcTryByjfbCem7d8R23FUFTUtZiYHAjCMUVf6 IQLA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=o6Ud3CD4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g1-v6si231312pld.236.2018.03.19.15.35.32; Mon, 19 Mar 2018 15:35:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=o6Ud3CD4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936147AbeCSWeW (ORCPT + 99 others); Mon, 19 Mar 2018 18:34:22 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:53298 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1032618AbeCSWdS (ORCPT ); Mon, 19 Mar 2018 18:33:18 -0400 Received: by mail-wm0-f66.google.com with SMTP id e194so17965703wmd.3 for ; Mon, 19 Mar 2018 15:33:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=YV7AO6YjRpHZ3TLM7Nsy4+A27rJytMvIcmhejcaUl+Q=; b=o6Ud3CD4+GPRY71Lq+7d1OpR6/Ib4kSUNh+0/1rk60SutMfluE0RmxsO/hw2izcZEv Je6c17EN2nb0WgNkGhmLj3lmKl1gSWp+yihUPggeiwDL0AOCRQ26ofBSf+LAXhaiXDOv d7ZXQj/hLO+xPy00DCtpBMKojZWPIbZFzS78L/MJCrzqoc6tnevXJ81GpSxc62q0J0yt vCwSa3CC+p9WXXy1kYKJwXOaFkO//5Nc/PLvK1Ejz/Pfv54MjOeImMHWhPAeFn+/B6np DQLIFASpAesmks1Nu5RxqO2g37Eb94uCO3PuoaQ3/H/YkWA30JoGcArkFvDdOZtYeIaH RQHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=YV7AO6YjRpHZ3TLM7Nsy4+A27rJytMvIcmhejcaUl+Q=; b=DM5xeHJ8Y/dgkxeCRltfMMklYWeSkiUbddlb1C26HEgeukG/P4BHAHfPaZ70P3cU1q QRl5Dtrhdg61KCNs5l57uuq41OQV5i+WgpEwmJFIY+N7NyQsOZ27FxB5axiDDNpw6NLa 4R0dreAzw/4eimUj28KcFZa60amZHqGWHiCl/TDO55uNF7hcfjGl5tfNZvI44+2mUp68 1eNq4dyaway2tgTcNUig0I2xcKGgBpY8cOvNuD6plikJ+/xOGmGUsu32C8RKAw0JCLrz 2pT9mbjUSpqrnm4om1YLyqVF4fH0aK9/v9qerIozJtlT2yRrhi3ZXCR9vu/WQEJfTZpQ i65w== X-Gm-Message-State: AElRT7FdETK9SdN2GEFgrtsmOt4AOPCO3bCrsSQN//6xJLwP8HqPMEr0 xYEIALYviDjXdKw80r6sQyCO9POZ X-Received: by 10.28.92.208 with SMTP id q199mr262741wmb.91.1521498795568; Mon, 19 Mar 2018 15:33:15 -0700 (PDT) Received: from [192.168.43.97] (cst-prg-20-149.cust.vodafone.cz. [46.135.20.149]) by smtp.gmail.com with ESMTPSA id q13sm276779wrg.56.2018.03.19.15.33.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Mar 2018 15:33:15 -0700 (PDT) Subject: Re: [PATCH] mtd: spi-nor: Fix Cadence QSPI page fault kernel panic To: thor.thayer@linux.intel.com, cyrille.pitchen@wedev4u.fr, dwmw2@infradead.org, computersforpeace@gmail.com, boris.brezillon@bootlin.com, richard@nod.at Cc: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org References: <1521485124-24882-1-git-send-email-thor.thayer@linux.intel.com> From: Marek Vasut Message-ID: Date: Mon, 19 Mar 2018 23:33:12 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <1521485124-24882-1-git-send-email-thor.thayer@linux.intel.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 03/19/2018 07:45 PM, thor.thayer@linux.intel.com wrote: > From: Thor Thayer > > The current Cadence QSPI driver caused a kernel panic when loading > a Root Filesystem from QSPI. The problem was caused by reading more > bytes than needed because the QSPI operated on 4 bytes at a time. > > [ 7.947754] spi_nor_read[1048]:from 0x037cad74, len 1 [bfe07fff] > [ 7.956247] cqspi_read[910]:offset 0x58502516, buffer=bfe07fff > [ 7.956247] > [ 7.966046] Unable to handle kernel paging request at virtual > address bfe08002 > [ 7.973239] pgd = eebfc000 > [ 7.975931] [bfe08002] *pgd=2fffb811, *pte=00000000, *ppte=00000000 > > Notice above how only 1 byte needed to be read but by reading 4 bytes > into the end of a mapped page, a unrecoverable page fault occurred. > > This patch uses a temporary buffer to hold the 4 bytes read and then > copies only the bytes required into the buffer. A min() function is > used to limit the length to prevent buffer overflows. > > Similar changes were made for the write routine. > > Signed-off-by: Thor Thayer > --- > drivers/mtd/spi-nor/cadence-quadspi.c | 39 ++++++++++++++++++++++++++++------- > 1 file changed, 31 insertions(+), 8 deletions(-) > > diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c > index 4b8e9183489a..b22ed982f896 100644 > --- a/drivers/mtd/spi-nor/cadence-quadspi.c > +++ b/drivers/mtd/spi-nor/cadence-quadspi.c > @@ -501,7 +501,8 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf, > void __iomem *reg_base = cqspi->iobase; > void __iomem *ahb_base = cqspi->ahb_base; > unsigned int remaining = n_rx; > - unsigned int bytes_to_read = 0; > + unsigned int mod_bytes, words_to_read, bytes_to_read = 0; > + u8 *rxbuf_end = rxbuf + n_rx; > int ret = 0; > > writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR); > @@ -533,9 +534,21 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf, > bytes_to_read *= cqspi->fifo_width; > bytes_to_read = bytes_to_read > remaining ? > remaining : bytes_to_read; > - ioread32_rep(ahb_base, rxbuf, > - DIV_ROUND_UP(bytes_to_read, 4)); > - rxbuf += bytes_to_read; > + /* Read 4 byte chunks before using single byte mode */ > + words_to_read = bytes_to_read / 4; > + mod_bytes = bytes_to_read % 4; > + if (words_to_read) { > + ioread32_rep(ahb_base, rxbuf, words_to_read); > + rxbuf += (words_to_read * 4); > + } > + if (mod_bytes) { > + unsigned int temp = ioread32(ahb_base); > + > + memcpy(rxbuf, &temp, min((unsigned int) > + (rxbuf_end - rxbuf), > + mod_bytes)); > + rxbuf += mod_bytes; > + } Wouldn't it make more sense to read in 4 byte increments all the time except for the one last read instead ? This code above where you always check for trailing bytes can make the next read cycle do ioreaad32 into unaligned memory address and thus cause slowdown. (consider the example where the controller first reports it has 5 bytes ready, then reports it has 7 bytes ready. If you read 4 bytes in the first cycle, wait a bit and then check how much data the controller has in the next cycle, it will be 8 bytes, all nicely aligned). Does it make sense ? -- Best regards, Marek Vasut