Messages in this thread | | | From | Linus Walleij <> | Date | Tue, 14 Sep 2021 00:43:46 +0200 | Subject | Re: [PATCH] ARM: decompressor: Avoid UNPREDICTABLE NOP encoding |
| |
On Wed, Sep 8, 2021 at 6:26 PM Andre Przywara <andre.przywara@arm.com> wrote:
> In the decompressor's head.S we need to start with an instruction that > is some kind of NOP, but also mimics as the PE/COFF header, when the > kernel is linked as an UEFI application. The clever solution here is > "tstne r0, #0x4d000", which in the worst case just clobbers the > condition flags, and bears the magic "MZ" signature in the lowest 16 bits. > > However the encoding used (0x13105a4d) is actually not valid, since bits > [15:12] are supposed to be 0 (written as "(0)" in the ARM ARM). > Violating this is UNPREDICTABLE, and *can* trigger an UNDEFINED > exception. Common Cortex cores seem to ignore those bits, but QEMU > chooses to trap, so the code goes fishing because of a missing exception > handler at this point. We are just saved by the fact that commonly (with > -kernel or when running from U-Boot) the "Z" bit is set, so the > instruction is never executed. See [0] for more details. > > To make things more robust and avoid UNPREDICTABLE behaviour in the > kernel code, lets replace this with a "two-instruction NOP": > The first instruction is an exclusive OR, the effect of which the second > instruction reverts. This does not leave any trace, neither in a > register nor in the condition flags. Also it's a perfectly valid > encoding. Kudos to Peter Maydell for coming up with this gem. > > [0] https://lore.kernel.org/qemu-devel/YTPIdbUCmwagL5%2FD@os.inf.tu-dresden.de/T/ > > Signed-off-by: Andre Przywara <andre.przywara@arm.com> > Reported-by: Adam Lackorzynski <adam@l4re.org> > Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Looks like a correct and clever solution to me! Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours, Linus Walleij
| |