From patchwork Wed Apr 23 06:37:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Kamensky X-Patchwork-Id: 4038981 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2BA7A9F501 for ; Wed, 23 Apr 2014 06:41:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 74DC82025B for ; Wed, 23 Apr 2014 06:41:51 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7FCEB20219 for ; Wed, 23 Apr 2014 06:41:45 +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 1WcqoK-00041U-R1; Wed, 23 Apr 2014 06:37:36 +0000 Received: from mail-qg0-f41.google.com ([209.85.192.41]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WcqoH-0003xU-Kx for linux-arm-kernel@lists.infradead.org; Wed, 23 Apr 2014 06:37:34 +0000 Received: by mail-qg0-f41.google.com with SMTP id z60so513230qgd.28 for ; Tue, 22 Apr 2014 23:37:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=7hdxls+CIo8NuoTJAN6zRygxTmijxdjKoBsAlKhJlg8=; b=lP6gRLcAY99OnE6a6f6Tfa98MfWgjwPt+ZaEjhdUqEAlV8xJn9viY2qeSEQgGslgbs rLJBPL9Uu2UEGvR3qyoxxxM0uRUyP+R3osewR0AO4xacgjt36sDR5FQscAKaDo9XmXz0 4gquPNiMbjMw5CP4EiUkGFwWI1J7d7gG/7pmVXa4pJpyxr+JTZP39fqRJf5s2EBCrpal gQuho+s5pvKUFvWCe9dH7pGdR2mCpXpyLsvk/ZqWica3FTuzK51jjCXcjhduFbml2Cef lxvqquEcez18Uk6fkLZsQYiJht7xUfRs265uglHKWhuuEpSTz7SAocYyUuwU0aUthx4m +8fQ== X-Gm-Message-State: ALoCoQnJmcLYKnPU/Ea5fhor8eqpQBtgpPWlugb1qkjunrdSBZr272UAbbkvbUTsBmoHWkxyDpv9 MIME-Version: 1.0 X-Received: by 10.140.27.70 with SMTP id 64mr1257051qgw.14.1398235031305; Tue, 22 Apr 2014 23:37:11 -0700 (PDT) Received: by 10.229.95.6 with HTTP; Tue, 22 Apr 2014 23:37:11 -0700 (PDT) In-Reply-To: <20140422094659.GB6979@arm.com> References: <1398119770-27817-1-git-send-email-victor.kamensky@linaro.org> <20140422094659.GB6979@arm.com> Date: Tue, 22 Apr 2014 23:37:11 -0700 Message-ID: Subject: Re: [PATCH] ARM64: disable DCACHE_WORD_ACCESS in big endian case From: Victor Kamensky To: Will Deacon X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140422_233733_757086_12A4808A X-CRM114-Status: GOOD ( 22.53 ) X-Spam-Score: 0.0 (/) Cc: Catalin Marinas , "linaro-kernel@lists.linaro.org" , "linux-arm-kernel@lists.infradead.org" X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,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 Hi Will, On 22 April 2014 02:46, Will Deacon wrote: > On Mon, Apr 21, 2014 at 11:36:10PM +0100, Victor Kamensky wrote: >> If DCACHE_WORD_ACCESS is enabled big endian image failed to >> boot. commit 7bc13fd33adb9536bd73965cd46bbf7377df097c >> "arm64: dcache: select DCACHE_WORD_ACCESS for little-endian CPUs" >> enabled this setting for both big endian and little endian >> cpus. And code in commit itself seems to be endian agnostic, >> however other, i.e C, code that sits under DCACHE_WORD_ACCESS >> seems to be not endian agnostic, I could not figure out where >> though. >> >> Solution is to enable DCACHE_WORD_ACCESS only if little >> endian mode is enabled (default). >> >> Signed-off-by: Victor Kamensky > > NAK, this really should work for big-endian machines. If it doesn't, we > should figure out why and fix the problem. Fair enough. Thanks for encouragement :) > As a start, can you share further details of the failure please? Failure was that kernel could not find init in case of initramfs image or could not do nfs mount in nfs boot case .. The issue turned out to be in another commit: "word-at-a-time: provide generic big-endian zero_bytemask implementation". Because of the issue in zero_bytemask function full_name_hash and hash_name were giving different hash results for the same path name (without slash). The issue is that (~0ul << 64) gives ~0ul not 0. I could not come up with more elegant solution other than use inline function that check shift value against type maximum width. Please take a look below. The patch below is not correctly formatted because of my gmail client line wrapping issue, and others. I will resend it with git send-mail later. For now could you please take a look and maybe suggest something more nicer other than inline function and explicit check. Also, if you can, could you please advise on what mailing list should I post it and who is appropriate maintainer. I could use get_maintainer.pl but would appreciate expert advice. With below patch aarch64 big-endian image with DCACHE_WORD_ACCESS enabled boots OK. From 47293e5e020ee8ad6233474a1eb13a149378de9d Mon Sep 17 00:00:00 2001 From: Victor Kamensky Date: Tue, 22 Apr 2014 21:05:07 -0700 Subject: [PATCH] word-at-a-time: fix generic big-endian zero_bytemask in max width case Commit 11ec50caedb56e3a87715edeff6a1852e6ae5416 "word-at-a-time: provide generic big-endian zero_bytemask implementation" added generic zero_bytemask implementation for big-endian system. But it gives incorrect result in case where fls gives shift value that equals to the width of unsigned long. As per C standard left shifting for the full width of type is undefined: "If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined." For example in arrach64 big-endian (~0ul << 64) will produce ~0ul. As result aarch64 big-endian is broken when CONFIG_DCACHE_WORD_ACCESS is defined and zero_bytemask is used. Solution to check shift size and if it is equal to width of unsigned long return 0. Signed-off-by: Victor Kamensky --- include/asm-generic/word-at-a-time.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h index d3909ef..6c80ead 100644 --- a/include/asm-generic/word-at-a-time.h +++ b/include/asm-generic/word-at-a-time.h @@ -50,10 +50,20 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct } #ifndef zero_bytemask +static inline unsigned long __zero_bytemask(unsigned long shift) +{ + unsigned long ret; + if (shift != BITS_PER_LONG) + ret = (~0ul << shift); + else + ret = 0; + return ret; +} + #ifdef CONFIG_64BIT -#define zero_bytemask(mask) (~0ul << fls64(mask)) +#define zero_bytemask(mask) (__zero_bytemask(fls64(mask))) #else -#define zero_bytemask(mask) (~0ul << fls(mask)) +#define zero_bytemask(mask) (__zero_bytemask(fls(mask))) #endif /* CONFIG_64BIT */ #endif /* zero_bytemask */