From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt0-x22b.google.com ([2607:f8b0:400d:c0d::22b]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1e2OcX-0004KJ-QS for linux-mtd@lists.infradead.org; Wed, 11 Oct 2017 21:32:56 +0000 Received: by mail-qt0-x22b.google.com with SMTP id f8so9576216qta.5 for ; Wed, 11 Oct 2017 14:32:31 -0700 (PDT) Date: Wed, 11 Oct 2017 17:32:28 -0400 (EDT) From: Nicolas Pitre To: Richard Weinberger cc: Boris Brezillon , "linux-mtd@lists.infradead.org" Subject: Re: [PATCH 1/5] MTD: mtdram: properly handle the phys argument in the point method In-Reply-To: Message-ID: References: <20171011032621.26979-1-nicolas.pitre@linaro.org> <20171011032621.26979-2-nicolas.pitre@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Wed, 11 Oct 2017, Richard Weinberger wrote: > On Wed, Oct 11, 2017 at 5:26 AM, Nicolas Pitre wrote: > > When the phys pointer is non null, the point method is expected to return > > the physical address for the pointed area. In the case of the mtdram > > driver we have to retrieve the physical address for the corresponding > > vmalloc area. However, there is no guarantee that the vmalloc area is > > made of physically contiguous pages. In that case we simply limit retlen > > to the actually contiguous pages. > > > > Signed-off-by: Nicolas Pitre > > --- > > drivers/mtd/devices/mtdram.c | 22 ++++++++++++++++++++++ > > 1 file changed, 22 insertions(+) > > > > diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c > > index cbd8547d7a..7dbee8e62f 100644 > > --- a/drivers/mtd/devices/mtdram.c > > +++ b/drivers/mtd/devices/mtdram.c > > @@ -13,6 +13,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -69,6 +70,27 @@ static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, > > { > > *virt = mtd->priv + from; > > *retlen = len; > > + > > + if (phys) { > > + /* limit retlen to the number of contiguous physical pages */ > > + unsigned long page_ofs = offset_in_page(*virt); > > + void *addr = *virt - page_ofs; > > + unsigned long pfn1, pfn0 = vmalloc_to_pfn(addr); > > + > > + *phys = __pfn_to_phys(pfn0) + page_ofs; > > + len += page_ofs; > > + while (len > PAGE_SIZE) { > > + len -= PAGE_SIZE; > > + addr += PAGE_SIZE; > > + pfn0++; > > + pfn1 = vmalloc_to_pfn(addr); > > + if (pfn1 != pfn0) { > > + *retlen = *virt - addr; In fact the above should be: *retlen = addr - *virt; Let me know if I should repost. Nicolas