Re: [PATCH RESEND] ARM: alignment: fix LSR #32 and ASR #32 offset decoding
Linus Walleij <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.linux.ports.arm.kernel |
|---|---|
| Message-ID | <CAD++jL=UQ4Hfib6EMPEChMpKQbSqPAmzQtshfExJ9XwhwqgErQ@mail.gmail.com> |
On Wed, Aug 12, 2026 at 8:51 PM Karl Mehltretter <[email protected]> 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 <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Please put this into Russell's patch tracker: https://www.arm.linux.org.uk/developer/patches/ Yours, Linus Walleij