From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5B9B0489866 for ; Thu, 13 Aug 2026 18:50:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786647040; cv=none; b=ZNvJTbfA4db0hWU96fqyEUQwnoVLW8cTATmuyYe+cD+r7dZ2J0GLyXkrqMB14IJ5CsxUieg+Dpaop/1OO52vIT4RA8+AXyPYAmiroZGPBgYecz5Uaqo0RBBEslQAKyA4RjZMZiHlQImcdikQdX97OWpWEQBtPj6coR2Pw7n85gw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786647040; c=relaxed/simple; bh=UqlujE87SZPUaAWV+3CYrV1L4tsDkWZ/Wf2g+PXcim8=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=OwPWuXO9GJgTL9or9n7cubCAVGufqlCvCqVveujzUEJ0KCq8vLEDknvP8vyPG6i6cn8zfp3U9YaCNu4t7OJFsOIqFN5iuVDDo3MFQPKUK0FcMPFvc7/uujUKZwrtNa79zzsHbhEuw65NNJBa4HpU6WkroQK+BIDz846xS6cpNVI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=jSlAxITQ; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="jSlAxITQ" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 746141BCA; Thu, 13 Aug 2026 11:50:31 -0700 (PDT) Received: from [10.2.212.23] (e121345-lin.cambridge.arm.com [10.2.212.23]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 311BF3F66F; Thu, 13 Aug 2026 11:50:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1786647035; bh=UqlujE87SZPUaAWV+3CYrV1L4tsDkWZ/Wf2g+PXcim8=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=jSlAxITQ8ytvrwEvfOjVSXrISd2ZMn2fDC4fGqTQWiW5V7lrZQalhYMUL3iXPcjMY T8TCNitVUWzZw5kFfMbDfN+TvqHDhPJjUBdPn4NbZZZHIVcT48Go7E849j4IE32dGq MXMecnGisUztYC3YPEinponeQWKgGzXsrmJub18I= Message-ID: <6f472cda-cd55-478b-afee-66ee2a0be63c@arm.com> Date: Thu, 13 Aug 2026 19:50:30 +0100 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH RESEND] ARM: alignment: fix LSR #32 and ASR #32 offset decoding To: Karl Mehltretter , Russell King Cc: Xie Yuanbin , Ard Biesheuvel , Linus Walleij , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org References: <20260812185057.1573-1-kmehltretter@gmail.com> From: Robin Murphy Content-Language: en-GB In-Reply-To: <20260812185057.1573-1-kmehltretter@gmail.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 12/08/2026 7:50 pm, Karl Mehltretter wrote: > The register-offset form of LDR/STR may apply a shift to Rm. Per > DecodeImmShift() (ARM ARM DDI0406C section A8.4.3, "Pseudocode details > of instruction-specified shifts and rotates"), an imm5 of 0 encodes a > shift of 32 for LSR and ASR; only LSL treats 0 as "no shift", and ROR > with 0 encodes RRX. > > do_alignment() special-cases RRX but not LSR or ASR, and IS_SHIFT() does > not filter these encodings out, so the block is entered with > shiftval == 0 and the offset becomes Rm instead of 0 (LSR #32) or the > replicated sign of Rm (ASR #32). Yikes! What kind of cursed compiler is emitting these nonsensical encodings? > do_alignment_finish_ldst() applies the offset to the base-register > writeback of the post-indexed form, so the emulated access itself uses > the correct faulting address but Rn is left holding the wrong value. > > Reproduced on ARM926EJ-S (versatile_defconfig, CONFIG_ALIGNMENT_TRAP=y, > gcc 13.3.0) with a misaligned base and Rm = 0x1000: > > ldr r0, [r1], r2, lsr #32 Rn advanced by 0x1000, must be unchanged > ldr r0, [r1], r2, asr #32 Rn advanced by 0x1000, must be unchanged > ldr r0, [r1], r2, asr #32 with Rm negative, Rn must decrease by 1 > > All three are correct with the patch applied, while a lsr #1 control > case is emulated correctly both before and after. While this does appear technically correct, the fact that it's gone unnoticed for 30 years and the relevant hardware is almost all virtually obsolete by now does make me wonder whether it's really worth messing with now, but at the same time, I guess it's a pretty low-impact change... Thanks, Robin. > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Assisted-by: Claude:claude-fable-5 > Signed-off-by: Karl Mehltretter > --- > Resending after two weeks without feedback; add ARM alignment reviewers > to Cc. > > arch/arm/mm/alignment.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c > index 812380f30ae3..49045e09ae18 100644 > --- a/arch/arm/mm/alignment.c > +++ b/arch/arm/mm/alignment.c > @@ -892,11 +892,17 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) > break; > > case SHIFT_LSR: > - offset.un >>= shiftval; > + if (shiftval == 0) > + offset.un = 0; > + else > + offset.un >>= shiftval; > break; > > case SHIFT_ASR: > - offset.sn >>= shiftval; > + if (shiftval == 0) > + offset.sn >>= 31; > + else > + offset.sn >>= shiftval; > break; > > case SHIFT_RORRRX: