On Wed, Sep 8, 2021 at 6:26 PM Andre Przywara <andre.przywara@xxxxxxx> 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@xxxxxxxxxxxxxxxxxxxx/T/ > > Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> > Reported-by: Adam Lackorzynski <adam@xxxxxxxx> > Suggested-by: Peter Maydell <peter.maydell@xxxxxxxxxx> Looks like a correct and clever solution to me! Reviewed-by: Linus Walleij <linus.walleij@xxxxxxxxxx> Yours, Linus Walleij