For Arm M-profile CPUs, on reset the CPU must load its initial PC and SP from a vector table in guest memory. Because we can't guarantee reset ordering, we have to handle the possibility that the ROM blob loader's reset function has not yet run when the CPU resets, in which case the data in an ELF file specified by the user won't be in guest memory to be read yet.
We work around the reset ordering problem by checking whether the ROM blob loader has any data for the address where the vector table is, using rom_ptr(). Unfortunately this does not handle the possibility of memory aliasing. For many M-profile boards, memory can be accessed via multiple possible physical addresses; if the board has the vector table at address X but the user's ELF file loads data via a different address Y which is an alias to the same underlying guest RAM then rom_ptr() will not find it. This series handles the possibility of aliasing by iterating through the whole FlatView of the CPU's address space checking for other mappings of the MemoryRegion corresponding to the location of the vector table. If we find any aliases we use rom_ptr() to see if the ROM blob loader has any data there. Changes from v1: * do a little bit more cleanup on flatview_for_each_range(): - switch return type to bool - document it * put the "rom_ptr() but handle aliases" functionality into a generally-available function rom_ptr_for_as() We discussed the idea of just making rom_ptr() itself handle the aliasing, but that would require looking at all the callsites to identify a good address space to use; it's also a bit more invasive to other platforms than I would like at this point in the release cycle. So I opted for "provide a new function" as a safer and simpler compromise. In many cases callers of rom_ptr() probably should be changed to use rom_ptr_for_as() at some point, though. I realised that although if we can get reset ordering sorted out we can remove this use of rom_ptr()/rom_ptr_from_as() from the Arm CPU reset function, we will still have the same "need to read the blob data directly" problem for board init functions which are the bulk of the callers of rom_ptr(). I suppose in theory we could rewrite those to postpone their accessing of the data until reset, but that sounds like it could get complicated. Anyway, that means that rom_ptr_for_as() might have a fairly long life. thanks -- PMM Peter Maydell (5): memory: Make flatview_cb return bool, not int memory: Document flatview_for_each_range() memory: Add offset_in_region to flatview_cb arguments hw/core/loader: Add new function rom_ptr_for_as() target/arm: Make M-profile VTOR loads on reset handle memory aliasing include/exec/memory.h | 32 ++++++++++++-- include/hw/loader.h | 31 ++++++++++++++ hw/core/loader.c | 75 +++++++++++++++++++++++++++++++++ softmmu/memory.c | 4 +- target/arm/cpu.c | 2 +- tests/qtest/fuzz/generic_fuzz.c | 11 +++-- 6 files changed, 145 insertions(+), 10 deletions(-) -- 2.20.1