On Mon, Jan 17, 2022 at 11:03 PM <marek.vasut@xxxxxxxxx> wrote: > It is possible to enforce the fault using 'isb' instruction placed > right after the read/write instruction which started the faulting > access. Add custom register accessors which perform the read/write > followed immediately by 'isb'. > > This way, the fault always happens on the 'isb' and in case of read, > which is located one instruction before the 'isb', it is now possible > to fix up the return value of the read in the asynchronous external > abort hook and make that read return all Fs. Hi Marek, As mentioned on IRC, I think this can be done a lot simpler, using a .text.fixup section hack: > +void rcar_pci_write_reg_workaround(struct rcar_pcie *pcie, u32 val, unsigned int reg) > +{ > +#ifdef CONFIG_ARM > + asm volatile( > + " str %0, [%1]\n" > + " isb\n" > + ::"r"(val), "r"(pcie->base + reg):"memory"); I think this would looks something like int error = 0; asm volatile( " str %1, [%2]\n" "1: isb\n" "2:\n" " pushsection .text.fixup,\"ax\"\n" " .align 2\n" \ "3: mov %0, %3\n" \ " b 2b\n" \ " .popsection\n" \ " .pushsection __ex_table,\"a\"\n" \ " .align 3\n" \ " .long 1b, 3b\n" \ " .popsection" \ : "+r" (error) :"r"(val), "r"(pcie->base + reg), "i" (-ENXIO):"memory"); This saves you from hand-parsing the instruction sequence, which tends to be even more fragile. After this, you just need to check the 'error' variable, which remains at 0 normally but contains -ENXIO if an exception hits. I'm not entirely sure this works for the particular exception you are getting, and it probably requires not registering the rcar_pcie_aarch32_abort_handler function, but it seems likely to work. Arnd