qemu/softmmu
Philippe Mathieu-Daudé 1a59bdba4b memory: Directly dispatch alias accesses on origin memory region
Since commit 2cdfcf272d ("memory: assign MemoryRegionOps to all
regions"), all newly created regions are assigned with
unassigned_mem_ops (which might be then overwritten).

When using aliased container regions, and there is no region mapped
at address 0 in the container, the memory_region_dispatch_read()
and memory_region_dispatch_write() calls incorrectly return the
container unassigned_mem_ops, because the alias offset is not used.

Consider the following setup:

    +--------------------+ < - - - - - - - - - - - +
    |     Container      |  mr
    |  (unassigned_mem)  |                         |
    |                    |
    |                    |                         |
    |                    |  alias_offset
    +                    + <- - - - - - +----------+---------+
    | +----------------+ |              |                    |
    | |  MemoryRegion0 | |              |                    |
    | +----------------+ |              |       Alias        |  addr1
    | |  MemoryRegion1 | | <~ ~  ~  ~ ~ |                    | <~~~~~~
    | +----------------+ |              |                    |
    |                    |              +--------------------+
    |                    |
    |                    |
    |                    |
    |                    |
    | +----------------+ |
    | |  MemoryRegionX | |
    | +----------------+ |
    | |  MemoryRegionY | |
    | +----------------+ |
    | |  MemoryRegionZ | |
    | +----------------+ |
    +--------------------+

The memory_region_init_alias() flow is:

  memory_region_init_alias()
  -> memory_region_init()
     -> object_initialize(TYPE_MEMORY_REGION)
        -> memory_region_initfn()
           -> mr->ops = &unassigned_mem_ops;

Later when accessing offset=addr1 via the alias, we expect to hit
MemoryRegion1. The memory_region_dispatch_read() flow is:

  memory_region_dispatch_read(addr1)
  -> memory_region_access_valid(mr)   <- addr1 offset is ignored
     -> mr->ops->valid.accepts()
        -> unassigned_mem_accepts()
        <- false
     <- false
   <- MEMTX_DECODE_ERROR

The caller gets a MEMTX_DECODE_ERROR while the access is OK.

Fix by dispatching aliases recursively, accessing its origin region
after adding the alias offset.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Peter Xu <peterx@redhat.com>
Message-Id: <20210418055708.820980-1-f4bug@amsat.org>
2022-01-18 10:45:02 +01:00
..
arch_init.c meson.build: Define QEMU_ARCH in config-target.h 2021-08-26 17:02:00 +01:00
balloon.c qapi: Restrict balloon-related commands to machine code 2020-09-29 15:41:35 +02:00
bootdevice.c softmmu: move more files to softmmu/ 2020-10-12 11:50:21 -04:00
cpu-throttle.c cpu-throttle: Remove timer_mod() from cpu_throttle_set() 2021-02-08 15:15:32 +01:00
cpu-timers.c icount: get rid of static variable 2021-04-01 09:40:45 +02:00
cpus.c util/oslib-posix: Forward SIGBUS to MCE handler under Linux 2022-01-07 19:30:13 -05:00
datadir.c vl: extract softmmu/datadir.c 2020-12-10 12:15:18 -05:00
device_tree.c device_tree: Add qemu_fdt_add_path 2021-10-20 18:17:54 -07:00
dma-helpers.c dma: Let dma_buf_rw() propagate MemTxResult 2021-12-31 01:05:27 +01:00
globals.c qmp: generalize watchdog-set-action to -no-reboot/-no-shutdown 2020-12-15 12:51:57 -05:00
icount.c icount: get rid of static variable 2021-04-01 09:40:45 +02:00
ioport.c softmmu: Add missing trace-events file 2020-09-09 17:15:18 +01:00
main.c meson: move SDL and SDL-image detection to meson 2020-08-21 06:30:44 -04:00
memory.c memory: Directly dispatch alias accesses on origin memory region 2022-01-18 10:45:02 +01:00
memory_mapping.c softmmu/memory_mapping: optimize for RamDiscardManager sections 2021-10-02 08:43:22 +02:00
meson.build seccomp: convert to meson 2021-01-06 10:21:20 +01:00
physmem.c accel/tcg: suppress IRQ check for special TBs 2021-11-29 15:12:37 +00:00
qdev-monitor.c pci,pc,virtio: bugfixes 2021-11-15 21:56:15 +01:00
qemu-seccomp.c seccomp: don't block getters for resource control syscalls 2021-07-14 14:15:52 +01:00
qtest.c qtest: add a QOM object for qtest 2021-05-26 14:49:45 +02:00
rtc.c qom: Allow optional sugar props 2021-02-08 16:57:37 +11:00
runstate-action.c runstate: cleanup reboot and panic actions 2021-01-21 13:00:41 +01:00
runstate.c runstate: Initialize Error * to NULL 2021-06-15 17:17:09 +02:00
timers-state.h qemu/atomic: Add aligned_{int64,uint64}_t types 2021-07-21 07:45:38 -10:00
tpm.c qapi: More complex uses of QAPI_LIST_APPEND 2021-01-28 08:08:45 +01:00
trace-events memory: make global_dirty_tracking a bitmask 2021-11-01 22:56:43 +01:00
trace.h softmmu: Add missing trace-events file 2020-09-09 17:15:18 +01:00
vl.c softmmu: fix device deletion events with -device JSON syntax 2022-01-14 12:03:16 +01:00