Re: [PATCH RESEND] ARM: alignment: fix LSR #32 and ASR #32 offset decoding

From: Linus Walleij

Date: Fri Aug 14 2026 - 02:50:20 EST


On Wed, Aug 12, 2026 at 8:51 PM Karl Mehltretter <kmehltretter@xxxxxxxxx> 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).
>
> 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.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Assisted-by: Claude:claude-fable-5
> Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>

Reviewed-by: Linus Walleij <linusw@xxxxxxxxxx>

Please put this into Russell's patch tracker:
https://www.arm.linux.org.uk/developer/patches/

Yours,
Linus Walleij