mbox series

[for-6.0,v2,0/5] arm: Make M-profile VTOR loads on reset handle memory aliasin

Message ID 20210318174823.18066-1-peter.maydell@linaro.org (mailing list archive)
Headers show
Series arm: Make M-profile VTOR loads on reset handle memory aliasin | expand

Message

Peter Maydell March 18, 2021, 5:48 p.m. UTC
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(-)