qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
@ 2015-07-08  9:46 Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 1/8] memory: get rid of memory_region_destructor_ram_from_ptr() Igor Mammedov
                   ` (8 more replies)
  0 siblings, 9 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

Changelog:
 v2->v3:
   * fixed(work-arouned) unmapping issues,
     now memory subsytem keeps track of HVA mapped
     regions and doesn't allow to map a new region
     at address where previos has benn mapped until
     previous region is gone
   * fixed offset calculations in memory_region_find_hva_range()
     in 2/8
   * redone MemorySection folding into HVA range for VHOST,
     now compacted memory map is temporary and passed only to vhost
     backend and doesn't touch original memory map used by QEMU
 v1->v2:
   * take into account Paolo's review comments
     * do not overload ram_addr
     * ifdef linux specific code
   * reseve HVA using API from exec.c instead of calling
     mmap() dircely from memory.c
   * support unmapping of HVA remapped region

When more than ~50 pc-dimm devices are hotplugged with
vhost enabled, QEMU will assert in vhost vhost_commit()
due to backend refusing to accept too many memory ranges.

Series introduces Reserved HVA MemoryRegion container
where to all hotplugged memory is remapped and passes
the single container range to vhost instead of multiple
memory ranges for each hotlugged pc-dimm device.

It's an alternative approach to increasing backend supported
memory regions limit. 

git branch for testing:
  https://github.com/imammedo/qemu/commits/vhost_one_hp_range_v3

Igor Mammedov (8):
  memory: get rid of memory_region_destructor_ram_from_ptr()
  memory: introduce MemoryRegion container with reserved HVA range
  pc: reserve hotpluggable memory range with
    memory_region_init_hva_range()
  pc: fix QEMU crashing when more than ~50 memory hotplugged
  exec: make sure that RAMBlock descriptor won't be leaked
  exec: add qemu_ram_unmap_hva() API for unmapping memory from HVA area
  memory: extend memory_region_add_subregion() to support error
    reporting
  memory: add support for deleting HVA mapped MemoryRegion

 exec.c                                   |  71 ++++++++++++-------
 hw/acpi/core.c                           |   6 +-
 hw/acpi/cpu_hotplug.c                    |   2 +-
 hw/acpi/ich9.c                           |   8 ++-
 hw/acpi/memory_hotplug.c                 |   3 +-
 hw/acpi/pcihp.c                          |   3 +-
 hw/acpi/piix4.c                          |   6 +-
 hw/alpha/typhoon.c                       |  16 ++---
 hw/arm/armv7m.c                          |   2 +-
 hw/arm/cubieboard.c                      |   2 +-
 hw/arm/digic_boards.c                    |   2 +-
 hw/arm/exynos4210.c                      |  12 ++--
 hw/arm/highbank.c                        |   4 +-
 hw/arm/integratorcp.c                    |   5 +-
 hw/arm/kzm.c                             |   9 ++-
 hw/arm/mainstone.c                       |   2 +-
 hw/arm/musicpal.c                        |   5 +-
 hw/arm/omap1.c                           |  59 +++++++++-------
 hw/arm/omap2.c                           |   8 ++-
 hw/arm/omap_sx1.c                        |  19 +++--
 hw/arm/palm.c                            |  14 ++--
 hw/arm/pxa2xx.c                          |  30 +++++---
 hw/arm/realview.c                        |   8 +--
 hw/arm/spitz.c                           |   2 +-
 hw/arm/stellaris.c                       |   7 +-
 hw/arm/stm32f205_soc.c                   |   8 ++-
 hw/arm/strongarm.c                       |   2 +-
 hw/arm/tosa.c                            |   2 +-
 hw/arm/versatilepb.c                     |   2 +-
 hw/arm/vexpress.c                        |  15 ++--
 hw/arm/virt.c                            |  12 ++--
 hw/arm/xilinx_zynq.c                     |   5 +-
 hw/arm/xlnx-ep108.c                      |   3 +-
 hw/arm/xlnx-zynqmp.c                     |   3 +-
 hw/block/onenand.c                       |   2 +-
 hw/block/pflash_cfi02.c                  |   3 +-
 hw/char/debugcon.c                       |   2 +-
 hw/char/mcf_uart.c                       |   2 +-
 hw/char/omap_uart.c                      |   2 +-
 hw/char/parallel.c                       |   2 +-
 hw/char/serial-pci.c                     |   2 +-
 hw/char/serial.c                         |   4 +-
 hw/char/sh_serial.c                      |   6 +-
 hw/core/platform-bus.c                   |   2 +-
 hw/core/sysbus.c                         |   4 +-
 hw/cpu/a15mpcore.c                       |   6 +-
 hw/cpu/a9mpcore.c                        |  18 +++--
 hw/cpu/arm11mpcore.c                     |  15 ++--
 hw/cris/axis_dev88.c                     |  10 +--
 hw/display/cirrus_vga.c                  |  11 +--
 hw/display/omap_dss.c                    |   2 +-
 hw/display/omap_lcdc.c                   |   2 +-
 hw/display/pxa2xx_lcd.c                  |   2 +-
 hw/display/sm501.c                       |   9 +--
 hw/display/tc6393xb.c                    |   5 +-
 hw/display/vga-isa-mm.c                  |   6 +-
 hw/display/vga-pci.c                     |   6 +-
 hw/display/vga.c                         |   3 +-
 hw/dma/etraxfs_dma.c                     |   3 +-
 hw/dma/i8257.c                           |   5 +-
 hw/dma/omap_dma.c                        |   4 +-
 hw/dma/rc4030.c                          |   4 +-
 hw/i386/kvm/pci-assign.c                 |   6 +-
 hw/i386/pc.c                             |  16 +++--
 hw/i386/pc_sysfw.c                       |   2 +-
 hw/ide/cmd646.c                          |   6 +-
 hw/ide/piix.c                            |   6 +-
 hw/ide/via.c                             |   6 +-
 hw/input/pxa2xx_keypad.c                 |   2 +-
 hw/intc/apic_common.c                    |   3 +-
 hw/intc/armv7m_nvic.c                    |   5 +-
 hw/intc/exynos4210_gic.c                 |   6 +-
 hw/intc/openpic.c                        |   2 +-
 hw/intc/realview_gic.c                   |   6 +-
 hw/intc/sh_intc.c                        |   6 +-
 hw/isa/apm.c                             |   2 +-
 hw/isa/isa-bus.c                         |   3 +-
 hw/isa/vt82c686.c                        |   7 +-
 hw/lm32/lm32_boards.c                    |   6 +-
 hw/lm32/milkymist.c                      |   3 +-
 hw/m68k/an5206.c                         |   5 +-
 hw/m68k/dummy_m68k.c                     |   2 +-
 hw/m68k/mcf5206.c                        |   2 +-
 hw/m68k/mcf5208.c                        |  10 +--
 hw/m68k/mcf_intc.c                       |   2 +-
 hw/mem/pc-dimm.c                         |   6 +-
 hw/microblaze/petalogix_ml605_mmu.c      |   6 +-
 hw/microblaze/petalogix_s3adsp1800_mmu.c |   5 +-
 hw/mips/gt64xxx_pci.c                    |   9 +--
 hw/mips/mips_fulong2e.c                  |   5 +-
 hw/mips/mips_jazz.c                      |  30 +++++---
 hw/mips/mips_malta.c                     |  17 +++--
 hw/mips/mips_mipssim.c                   |  11 +--
 hw/mips/mips_r4k.c                       |  14 ++--
 hw/misc/debugexit.c                      |   2 +-
 hw/misc/ivshmem.c                        |   4 +-
 hw/misc/macio/macio.c                    |  24 ++++---
 hw/misc/omap_gpmc.c                      |   7 +-
 hw/misc/omap_l4.c                        |   3 +-
 hw/misc/omap_sdrc.c                      |   2 +-
 hw/misc/pc-testdev.c                     |  11 +--
 hw/moxie/moxiesim.c                      |   4 +-
 hw/net/fsl_etsec/etsec.c                 |   3 +-
 hw/net/mcf_fec.c                         |   2 +-
 hw/openrisc/openrisc_sim.c               |   6 +-
 hw/pci-host/apb.c                        |   3 +-
 hw/pci-host/grackle.c                    |   2 +-
 hw/pci-host/piix.c                       |   3 +-
 hw/pci-host/ppce500.c                    |  13 ++--
 hw/pci-host/prep.c                       |  24 ++++---
 hw/pci-host/q35.c                        |   8 ++-
 hw/pci-host/uninorth.c                   |   4 +-
 hw/pci/msix.c                            |   6 +-
 hw/pci/pcie_host.c                       |   3 +-
 hw/pci/shpc.c                            |   2 +-
 hw/pcmcia/pxa2xx.c                       |   6 +-
 hw/ppc/e500.c                            |  14 ++--
 hw/ppc/mac_newworld.c                    |  14 ++--
 hw/ppc/mac_oldworld.c                    |   6 +-
 hw/ppc/ppc405_boards.c                   |  12 ++--
 hw/ppc/ppc405_uc.c                       |  16 +++--
 hw/ppc/ppc440_bamboo.c                   |   3 +-
 hw/ppc/ppc4xx_devs.c                     |   4 +-
 hw/ppc/ppc4xx_pci.c                      |   9 ++-
 hw/ppc/prep.c                            |   4 +-
 hw/ppc/spapr.c                           |   4 +-
 hw/ppc/spapr_pci.c                       |   8 +--
 hw/ppc/spapr_pci_vfio.c                  |   2 +-
 hw/ppc/virtex_ml507.c                    |   3 +-
 hw/s390x/s390-virtio-ccw.c               |   2 +-
 hw/s390x/s390-virtio.c                   |   2 +-
 hw/s390x/sclp.c                          |   3 +-
 hw/sd/omap_mmc.c                         |   2 +-
 hw/sd/pxa2xx_mmci.c                      |   2 +-
 hw/sh4/r2d.c                             |   5 +-
 hw/sh4/sh7750.c                          |  21 ++++--
 hw/sh4/sh_pci.c                          |   6 +-
 hw/sh4/shix.c                            |   6 +-
 hw/sparc/leon3.c                         |   6 +-
 hw/sparc64/sun4u.c                       |   2 +-
 hw/timer/m48t59.c                        |   3 +-
 hw/timer/sh_timer.c                      |   6 +-
 hw/tpm/tpm_tis.c                         |   2 +-
 hw/tricore/tricore_testboard.c           |  12 ++--
 hw/unicore32/puv3.c                      |   6 +-
 hw/usb/hcd-ehci-sysbus.c                 |   2 +-
 hw/usb/hcd-ehci.c                        |   8 ++-
 hw/usb/hcd-xhci.c                        |  15 ++--
 hw/vfio/common.c                         |   2 +-
 hw/vfio/pci.c                            |   6 +-
 hw/virtio/vhost.c                        |  47 +++++++++++-
 hw/virtio/virtio-pci.c                   |   3 +-
 hw/xtensa/sim.c                          |   5 +-
 hw/xtensa/xtfpga.c                       |  18 ++---
 include/exec/cpu-common.h                |   3 +
 include/exec/memory.h                    |  49 ++++++++++++-
 include/exec/ram_addr.h                  |   1 -
 include/hw/virtio/vhost.h                |   1 +
 ioport.c                                 |   2 +-
 memory.c                                 | 118 ++++++++++++++++++++++++++++---
 numa.c                                   |   2 +-
 161 files changed, 867 insertions(+), 458 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] [RFC v3 1/8] memory: get rid of memory_region_destructor_ram_from_ptr()
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
@ 2015-07-08  9:46 ` Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 2/8] memory: introduce MemoryRegion container with reserved HVA range Igor Mammedov
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

memory_region_destructor_ram() -> qemu_ram_free()
calls reclaim_ramblock() which does:

  if (!(block->flags & RAM_PREALLOC))
      free_host_memory()

  g_free(block)

while
  memory_region_destructor_ram_from_ptr() -> qemu_ram_free_from_ptr()
  calls g_free_rcu(block, rcu) results -> g_free(block)

and for memory_region_init_ram_ptr() we set RAM_PREALLOC
so qemu_ram_free() degrades to just g_free(block) so we could
just use qemu_ram_free() instead of qemu_ram_free_from_ptr().

Signed-off-by: Igor Mammedov <imammedo@redhat.com>

Conflicts:
	memory.c
---
 exec.c                  | 19 -------------------
 include/exec/ram_addr.h |  1 -
 memory.c                |  7 +------
 3 files changed, 1 insertion(+), 26 deletions(-)

diff --git a/exec.c b/exec.c
index 251dc79..eb5ece7 100644
--- a/exec.c
+++ b/exec.c
@@ -1571,25 +1571,6 @@ ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t maxsz,
     return qemu_ram_alloc_internal(size, maxsz, resized, NULL, true, mr, errp);
 }
 
-void qemu_ram_free_from_ptr(ram_addr_t addr)
-{
-    RAMBlock *block;
-
-    qemu_mutex_lock_ramlist();
-    QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
-        if (addr == block->offset) {
-            QLIST_REMOVE_RCU(block, next);
-            ram_list.mru_block = NULL;
-            /* Write list before version */
-            smp_wmb();
-            ram_list.version++;
-            g_free_rcu(block, rcu);
-            break;
-        }
-    }
-    qemu_mutex_unlock_ramlist();
-}
-
 static void reclaim_ramblock(RAMBlock *block)
 {
     if (block->flags & RAM_PREALLOC) {
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index c113f21..9c10462 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -37,7 +37,6 @@ int qemu_get_ram_fd(ram_addr_t addr);
 void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
 void *qemu_get_ram_ptr(ram_addr_t addr);
 void qemu_ram_free(ram_addr_t addr);
-void qemu_ram_free_from_ptr(ram_addr_t addr);
 
 int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp);
 
diff --git a/memory.c b/memory.c
index 5a0cc66..ec07ae8 100644
--- a/memory.c
+++ b/memory.c
@@ -864,11 +864,6 @@ static void memory_region_destructor_alias(MemoryRegion *mr)
     memory_region_unref(mr->alias);
 }
 
-static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
-{
-    qemu_ram_free_from_ptr(mr->ram_addr);
-}
-
 static void memory_region_destructor_rom_device(MemoryRegion *mr)
 {
     qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
@@ -1251,7 +1246,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
     memory_region_init(mr, owner, name, size);
     mr->ram = true;
     mr->terminates = true;
-    mr->destructor = memory_region_destructor_ram_from_ptr;
+    mr->destructor = memory_region_destructor_ram;
     mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
 
     /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [RFC v3 2/8] memory: introduce MemoryRegion container with reserved HVA range
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 1/8] memory: get rid of memory_region_destructor_ram_from_ptr() Igor Mammedov
@ 2015-07-08  9:46 ` Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 3/8] pc: reserve hotpluggable memory range with memory_region_init_hva_range() Igor Mammedov
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

Patch adds memory_region_init_hva_range() and
memory_region_find_hva_range() API to allocate and lookup
reserved HVA MemoryRegion.

MemoryRegion with reserved HVA range will be used for
providing linear 1:1 HVA->GVA mapping for RAM MemoryRegion-s
that is added as subregions inside it.

It will be used for memory hotplug and vhost integration
reducing all hotplugged MemoryRegions down to one
memory range descriptor, which allows to overcome
vhost's limitation on number of allowed memory ranges.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
RFC->v1:
  - rename:
       memory_region_init_rsvd_hva -> memory_region_init_hva_range
       memory_region_find_rsvd_hva -> memory_region_find_hva_range
  - replace using ram_addr with "void *rsvd_hva"
  - guard linux specific calls with ifdef
  - split memory reservation into qemu_ram_reserve_hva()

memory_region_find_hva_range fixup
---
 exec.c                    | 31 +++++++++++++++++++++++++++++++
 include/exec/cpu-common.h |  2 ++
 include/exec/memory.h     | 44 ++++++++++++++++++++++++++++++++++++++++++--
 memory.c                  | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index eb5ece7..41d14fc 100644
--- a/exec.c
+++ b/exec.c
@@ -1339,6 +1339,37 @@ static int memory_try_enable_merging(void *addr, size_t len)
     return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
 }
 
+#ifdef __linux__
+void *qemu_ram_reserve_hva(ram_addr_t length)
+{
+    return mmap(0, length, PROT_NONE,
+                MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+}
+
+void qemu_ram_remap_hva(ram_addr_t addr, void *new_hva)
+{
+    RAMBlock *block = find_ram_block(addr);
+
+    assert(block);
+    block->host = mremap(block->host, block->used_length,
+                      block->used_length,
+                      MREMAP_MAYMOVE | MREMAP_FIXED, new_hva);
+    memory_try_enable_merging(block->host, block->used_length);
+    qemu_ram_setup_dump(block->host, block->used_length);
+}
+#else
+void *qemu_ram_reserve_hva(ram_addr_t length)
+{
+    return NULL;
+}
+
+void qemu_ram_remap_hva(ram_addr_t addr, void *new_hva)
+{
+    assert(0);
+}
+#endif
+
+
 /* Only legal before guest might have detected the memory size: e.g. on
  * incoming migration, or right after reset.
  *
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 9fb1d54..301f50b 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -62,6 +62,8 @@ typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
 
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
+void *qemu_ram_reserve_hva(ram_addr_t length);
+void qemu_ram_remap_hva(ram_addr_t addr, void *new_hva);
 /* This should not be used by devices.  */
 MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 1394715..b9e6112 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -173,6 +173,7 @@ struct MemoryRegion {
     bool terminates;
     bool romd_mode;
     bool ram;
+    void *rsvd_hva;
     bool skip_dump;
     bool readonly; /* For RAM regions */
     bool enabled;
@@ -283,6 +284,25 @@ void memory_region_init(MemoryRegion *mr,
                         struct Object *owner,
                         const char *name,
                         uint64_t size);
+/**
+ * memory_region_init_hva_range: Initialize a reserved HVA memory region
+ *
+ * The container for RAM memory regions.
+ * When adding subregion with memory_region_add_subregion(), subregion's
+ * backing host memory will be remapped to inside the reserved by this
+ * region HVA.
+ * Supported only on Linux. If memory reservation and remapping is not
+ * implemented for platform, this call degrades to regular memory_region_init().
+ *
+ * @mr: the #MemoryRegion to be initialized
+ * @owner: the object that tracks the region's reference count
+ * @name: used for debugging; not visible to the user or ABI
+ * @size: size of the region; any subregions beyond this size will be clipped
+ */
+void memory_region_init_hva_range(MemoryRegion *mr,
+                                  struct Object *owner,
+                                  const char *name,
+                                  uint64_t size);
 
 /**
  * memory_region_ref: Add 1 to a memory region's reference count
@@ -634,8 +654,8 @@ int memory_region_get_fd(MemoryRegion *mr);
  * memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
  *
  * Returns a host pointer to a RAM memory region (created with
- * memory_region_init_ram() or memory_region_init_ram_ptr()).  Use with
- * care.
+ * memory_region_init_ram() or memory_region_init_ram_ptr()) or
+ * memory_region_init_hva_range(). Use with care.
  *
  * @mr: the memory region being queried.
  */
@@ -1052,6 +1072,26 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
                                        hwaddr addr, uint64_t size);
 
 /**
+ * memory_region_find_hva_range: finds a parent MemoryRegion with
+ * reserved HVA and translates it into a #MemoryRegionSection.
+ *
+ * Locates the first parent #MemoryRegion of @mr that is
+ * of reserved HVA type.
+ *
+ * Returns a #MemoryRegionSection that describes a reserved HVA
+ * memory region.
+ *    .@offset_within_address_space is offset of found
+ *      (in the .@mr field) memory region relative to the address
+ *      space that contains it.
+ *    .@offset_within_region is offset of @mr relative
+ *      to the returned region (in the .@mr field).
+ *    .@size is size of found memory region
+ *
+ * @mr: a MemoryRegion whose HVA parent is looked up
+ */
+MemoryRegionSection memory_region_find_hva_range(MemoryRegion *mr);
+
+/**
  * address_space_sync_dirty_bitmap: synchronize the dirty log for all memory
  *
  * Synchronizes the dirty page log for an entire address space.
diff --git a/memory.c b/memory.c
index ec07ae8..4558d85 100644
--- a/memory.c
+++ b/memory.c
@@ -929,6 +929,15 @@ void memory_region_init(MemoryRegion *mr,
     }
 }
 
+void memory_region_init_hva_range(MemoryRegion *mr,
+                                  Object *owner,
+                                  const char *name,
+                                  uint64_t size)
+{
+    memory_region_init(mr, owner, name, size);
+    mr->rsvd_hva = qemu_ram_reserve_hva(memory_region_size(mr));
+}
+
 static void memory_region_get_addr(Object *obj, Visitor *v, void *opaque,
                                    const char *name, Error **errp)
 {
@@ -1517,6 +1526,10 @@ int memory_region_get_fd(MemoryRegion *mr)
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
 {
+    if (mr->rsvd_hva) {
+        return mr->rsvd_hva;
+    }
+
     if (mr->alias) {
         return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
     }
@@ -1755,6 +1768,14 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
     assert(!subregion->container);
     subregion->container = mr;
     subregion->addr = offset;
+
+    if (subregion->ram) {
+        if (mr->rsvd_hva) {
+            qemu_ram_remap_hva(subregion->ram_addr,
+                memory_region_get_ram_ptr(mr) + subregion->addr);
+        }
+    }
+
     memory_region_update_container_subregions(subregion);
 }
 
@@ -1897,6 +1918,32 @@ bool memory_region_is_mapped(MemoryRegion *mr)
     return mr->container ? true : false;
 }
 
+MemoryRegionSection memory_region_find_hva_range(MemoryRegion *mr)
+{
+    MemoryRegionSection ret = { .mr = NULL };
+    MemoryRegion *hva_container = NULL;
+    hwaddr addr = 0;
+    MemoryRegion *root;
+
+    for (root = mr; root->container; root = root->container) {
+        if (!hva_container && root->rsvd_hva) {
+            hva_container = root;
+            ret.offset_within_region = addr;
+        }
+        addr += root->addr;
+    }
+
+    ret.address_space = memory_region_to_address_space(root);
+    if (!ret.address_space || !hva_container) {
+        return ret;
+    }
+
+    ret.mr = hva_container;
+    ret.offset_within_address_space = addr;
+    ret.size = int128_make64(memory_region_size(ret.mr));
+    return ret;
+}
+
 MemoryRegionSection memory_region_find(MemoryRegion *mr,
                                        hwaddr addr, uint64_t size)
 {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [RFC v3 3/8] pc: reserve hotpluggable memory range with memory_region_init_hva_range()
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 1/8] memory: get rid of memory_region_destructor_ram_from_ptr() Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 2/8] memory: introduce MemoryRegion container with reserved HVA range Igor Mammedov
@ 2015-07-08  9:46 ` Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 4/8] pc: fix QEMU crashing when more than ~50 memory hotplugged Igor Mammedov
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

It makes sure that all hotplugged memory will be put in
continuos HVA range allowing to use 1:1 GVA<->HVA mapping.

1:1 mapping will be used by vhost to reduce number of memory
ranges for hotplugged memory to a single range that covers
all hotpluggable memory address space.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 7959b44..bd79d25 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1311,8 +1311,8 @@ FWCfgState *pc_memory_init(MachineState *machine,
             exit(EXIT_FAILURE);
         }
 
-        memory_region_init(&pcms->hotplug_memory.mr, OBJECT(pcms),
-                           "hotplug-memory", hotplug_mem_size);
+        memory_region_init_hva_range(&pcms->hotplug_memory.mr, OBJECT(pcms),
+                                     "hotplug-memory", hotplug_mem_size);
         memory_region_add_subregion(system_memory, pcms->hotplug_memory.base,
                                     &pcms->hotplug_memory.mr);
     }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [RFC v3 4/8] pc: fix QEMU crashing when more than ~50 memory hotplugged
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
                   ` (2 preceding siblings ...)
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 3/8] pc: reserve hotpluggable memory range with memory_region_init_hva_range() Igor Mammedov
@ 2015-07-08  9:46 ` Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 5/8] exec: make sure that RAMBlock descriptor won't be leaked Igor Mammedov
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

QEMU asserts in vhost due to hitting vhost backend limit
on number of supported memory regions.

Describe all hotplugged memory as one continuos range
to vhost with linear 1:1 HVA->GPA mapping in backend.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/virtio/vhost.c         | 47 ++++++++++++++++++++++++++++++++++++++++++++---
 include/hw/virtio/vhost.h |  1 +
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 2712c6f..7bc27f0 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -432,6 +432,10 @@ static void vhost_set_memory(MemoryListener *listener,
 
     assert(size);
 
+    if (!dev->rsvd_hva.mr) {
+        dev->rsvd_hva = memory_region_find_hva_range(section->mr);
+    }
+
     /* Optimize no-change case. At least cirrus_vga does this a lot at this time. */
     ram = memory_region_get_ram_ptr(section->mr) + section->offset_within_region;
     if (add) {
@@ -472,6 +476,42 @@ static void vhost_begin(MemoryListener *listener)
     dev->mem_changed_start_addr = -1;
 }
 
+static int vhost_set_mem_table(struct vhost_dev *dev)
+{
+    hwaddr start_addr = 0;
+    ram_addr_t size = 0;
+    struct vhost_memory *mem;
+    int r, i;
+
+    /* drop memory ranges from continuos HVA */
+    mem = g_memdup(dev->mem, offsetof(struct vhost_memory, regions) +
+                       dev->mem->nregions * sizeof dev->mem->regions[0]);
+    start_addr = dev->rsvd_hva.offset_within_address_space;
+    size = int128_get64(dev->rsvd_hva.size);
+    for (i = 0; i < mem->nregions; i++) {
+        if (mem->regions[i].guest_phys_addr >= start_addr &&
+            mem->regions[i].guest_phys_addr < start_addr + size) {
+            mem->nregions--;
+            memmove(&mem->regions[i], &mem->regions[i + 1],
+                    (mem->nregions - i) * sizeof mem->regions[0]);
+        }
+    }
+    /* add one continuos HVA entry if memory ranges from it is present */
+    if (dev->mem->nregions > mem->nregions) {
+        struct vhost_memory_region *reg = &mem->regions[mem->nregions];
+
+        reg->guest_phys_addr = start_addr;
+        reg->memory_size = size;
+        reg->userspace_addr =
+            (__u64)memory_region_get_ram_ptr(dev->rsvd_hva.mr);
+        mem->nregions++;
+    }
+
+    r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, mem);
+    g_free(mem);
+    return r;
+}
+
 static void vhost_commit(MemoryListener *listener)
 {
     struct vhost_dev *dev = container_of(listener, struct vhost_dev,
@@ -500,7 +540,7 @@ static void vhost_commit(MemoryListener *listener)
     }
 
     if (!dev->log_enabled) {
-        r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem);
+        r = vhost_set_mem_table(dev);
         assert(r >= 0);
         dev->memory_changed = false;
         return;
@@ -513,7 +553,7 @@ static void vhost_commit(MemoryListener *listener)
     if (dev->log_size < log_size) {
         vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER);
     }
-    r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem);
+    r = vhost_set_mem_table(dev);
     assert(r >= 0);
     /* To log less, can only decrease log size after table update. */
     if (dev->log_size > log_size + VHOST_LOG_BUFFER) {
@@ -956,6 +996,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
         migrate_add_blocker(hdev->migration_blocker);
     }
     hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions));
+    memset(&hdev->rsvd_hva, 0, sizeof hdev->rsvd_hva);
     hdev->n_mem_sections = 0;
     hdev->mem_sections = NULL;
     hdev->log = NULL;
@@ -1119,7 +1160,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
     if (r < 0) {
         goto fail_features;
     }
-    r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_MEM_TABLE, hdev->mem);
+    r = vhost_set_mem_table(hdev);
     if (r < 0) {
         r = -errno;
         goto fail_mem;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index dd51050..d41bf2f 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -40,6 +40,7 @@ struct vhost_dev {
     struct vhost_memory *mem;
     int n_mem_sections;
     MemoryRegionSection *mem_sections;
+    MemoryRegionSection rsvd_hva;
     struct vhost_virtqueue *vqs;
     int nvqs;
     /* the first virtqueue which would be used by this vhost dev */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [RFC v3 5/8] exec: make sure that RAMBlock descriptor won't be leaked
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
                   ` (3 preceding siblings ...)
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 4/8] pc: fix QEMU crashing when more than ~50 memory hotplugged Igor Mammedov
@ 2015-07-08  9:46 ` Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 6/8] exec: add qemu_ram_unmap_hva() API for unmapping memory from HVA area Igor Mammedov
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

HVA remapped file backed RAMBlock shouldn't be freed
with munmap() as it will create a hole in HVA area
but file descriptor should be freed so it won't leak.

Rearrange code so that file descriptor is freed always
if it's been used and drop unnecessary munmap()
call/branch because qemu_anon_ram_free() is doing the same.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 exec.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/exec.c b/exec.c
index 41d14fc..ebbcfe9 100644
--- a/exec.c
+++ b/exec.c
@@ -1608,14 +1608,14 @@ static void reclaim_ramblock(RAMBlock *block)
         ;
     } else if (xen_enabled()) {
         xen_invalidate_map_cache_entry(block->host);
-#ifndef _WIN32
-    } else if (block->fd >= 0) {
-        munmap(block->host, block->max_length);
-        close(block->fd);
-#endif
     } else {
         qemu_anon_ram_free(block->host, block->max_length);
     }
+#ifndef _WIN32
+    if (block->fd >= 0) {
+        close(block->fd);
+    }
+#endif
     g_free(block);
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [RFC v3 6/8] exec: add qemu_ram_unmap_hva() API for unmapping memory from HVA area
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
                   ` (4 preceding siblings ...)
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 5/8] exec: make sure that RAMBlock descriptor won't be leaked Igor Mammedov
@ 2015-07-08  9:46 ` Igor Mammedov
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting Igor Mammedov
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

it will allow to return atomically return RAMBlock's host
address range into continuos HVA area so that no hole
would appear in there.

also mark RAMBlock with RAM_PREALLOC flag so it won't be
umapped as conventional memory by
  reclaim_ramblock()->qemu_anon_ram_free()

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 exec.c                    | 11 +++++++++++
 include/exec/cpu-common.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/exec.c b/exec.c
index ebbcfe9..ec8f234 100644
--- a/exec.c
+++ b/exec.c
@@ -1346,11 +1346,22 @@ void *qemu_ram_reserve_hva(ram_addr_t length)
                 MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
 }
 
+void qemu_ram_unmap_hva(ram_addr_t addr)
+{
+    RAMBlock *block = find_ram_block(addr);
+
+    assert(block);
+    mmap(block->host, block->used_length, PROT_NONE,
+         MAP_FIXED | MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+}
+
 void qemu_ram_remap_hva(ram_addr_t addr, void *new_hva)
 {
     RAMBlock *block = find_ram_block(addr);
 
     assert(block);
+    assert(!(block->flags & RAM_PREALLOC));
+    block->flags |= RAM_PREALLOC;
     block->host = mremap(block->host, block->used_length,
                       block->used_length,
                       MREMAP_MAYMOVE | MREMAP_FIXED, new_hva);
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 301f50b..4da5cd7 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -64,6 +64,7 @@ typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 void *qemu_ram_reserve_hva(ram_addr_t length);
 void qemu_ram_remap_hva(ram_addr_t addr, void *new_hva);
+void qemu_ram_unmap_hva(ram_addr_t addr);
 /* This should not be used by devices.  */
 MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
                   ` (5 preceding siblings ...)
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 6/8] exec: add qemu_ram_unmap_hva() API for unmapping memory from HVA area Igor Mammedov
@ 2015-07-08  9:46 ` Igor Mammedov
  2015-07-08 11:03   ` Michael S. Tsirkin
  2015-07-08 11:09   ` Peter Maydell
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 8/8] memory: add support for deleting HVA mapped MemoryRegion Igor Mammedov
  2015-07-08 10:01 ` [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Michael S. Tsirkin
  8 siblings, 2 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

extends memory_region_add_subregion() by adding Error**
argument to allow t fail and return a error from it.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/core.c                           |  6 ++--
 hw/acpi/cpu_hotplug.c                    |  2 +-
 hw/acpi/ich9.c                           |  8 +++--
 hw/acpi/memory_hotplug.c                 |  3 +-
 hw/acpi/pcihp.c                          |  3 +-
 hw/acpi/piix4.c                          |  6 ++--
 hw/alpha/typhoon.c                       | 16 ++++-----
 hw/arm/armv7m.c                          |  2 +-
 hw/arm/cubieboard.c                      |  2 +-
 hw/arm/digic_boards.c                    |  2 +-
 hw/arm/exynos4210.c                      | 12 +++----
 hw/arm/highbank.c                        |  4 +--
 hw/arm/integratorcp.c                    |  5 +--
 hw/arm/kzm.c                             |  9 +++--
 hw/arm/mainstone.c                       |  2 +-
 hw/arm/musicpal.c                        |  5 +--
 hw/arm/omap1.c                           | 59 ++++++++++++++++++--------------
 hw/arm/omap2.c                           |  8 +++--
 hw/arm/omap_sx1.c                        | 19 ++++++----
 hw/arm/palm.c                            | 14 +++++---
 hw/arm/pxa2xx.c                          | 30 ++++++++++------
 hw/arm/realview.c                        |  8 ++---
 hw/arm/spitz.c                           |  2 +-
 hw/arm/stellaris.c                       |  7 ++--
 hw/arm/stm32f205_soc.c                   |  8 +++--
 hw/arm/strongarm.c                       |  2 +-
 hw/arm/tosa.c                            |  2 +-
 hw/arm/versatilepb.c                     |  2 +-
 hw/arm/vexpress.c                        | 15 ++++----
 hw/arm/virt.c                            | 12 ++++---
 hw/arm/xilinx_zynq.c                     |  5 +--
 hw/arm/xlnx-ep108.c                      |  3 +-
 hw/arm/xlnx-zynqmp.c                     |  3 +-
 hw/block/onenand.c                       |  2 +-
 hw/block/pflash_cfi02.c                  |  3 +-
 hw/char/debugcon.c                       |  2 +-
 hw/char/mcf_uart.c                       |  2 +-
 hw/char/omap_uart.c                      |  2 +-
 hw/char/parallel.c                       |  2 +-
 hw/char/serial-pci.c                     |  2 +-
 hw/char/serial.c                         |  4 +--
 hw/char/sh_serial.c                      |  6 ++--
 hw/core/platform-bus.c                   |  2 +-
 hw/core/sysbus.c                         |  4 +--
 hw/cpu/a15mpcore.c                       |  6 ++--
 hw/cpu/a9mpcore.c                        | 18 ++++++----
 hw/cpu/arm11mpcore.c                     | 15 +++++---
 hw/cris/axis_dev88.c                     | 10 +++---
 hw/display/cirrus_vga.c                  | 11 +++---
 hw/display/omap_dss.c                    |  2 +-
 hw/display/omap_lcdc.c                   |  2 +-
 hw/display/pxa2xx_lcd.c                  |  2 +-
 hw/display/sm501.c                       |  9 ++---
 hw/display/tc6393xb.c                    |  5 +--
 hw/display/vga-isa-mm.c                  |  6 ++--
 hw/display/vga-pci.c                     |  6 ++--
 hw/display/vga.c                         |  3 +-
 hw/dma/etraxfs_dma.c                     |  3 +-
 hw/dma/i8257.c                           |  5 +--
 hw/dma/omap_dma.c                        |  4 +--
 hw/dma/rc4030.c                          |  4 +--
 hw/i386/kvm/pci-assign.c                 |  6 ++--
 hw/i386/pc.c                             | 12 ++++---
 hw/i386/pc_sysfw.c                       |  2 +-
 hw/ide/cmd646.c                          |  6 ++--
 hw/ide/piix.c                            |  6 ++--
 hw/ide/via.c                             |  6 ++--
 hw/input/pxa2xx_keypad.c                 |  2 +-
 hw/intc/apic_common.c                    |  3 +-
 hw/intc/armv7m_nvic.c                    |  5 +--
 hw/intc/exynos4210_gic.c                 |  6 ++--
 hw/intc/openpic.c                        |  2 +-
 hw/intc/realview_gic.c                   |  6 ++--
 hw/intc/sh_intc.c                        |  6 ++--
 hw/isa/apm.c                             |  2 +-
 hw/isa/isa-bus.c                         |  3 +-
 hw/isa/vt82c686.c                        |  7 ++--
 hw/lm32/lm32_boards.c                    |  6 ++--
 hw/lm32/milkymist.c                      |  3 +-
 hw/m68k/an5206.c                         |  5 +--
 hw/m68k/dummy_m68k.c                     |  2 +-
 hw/m68k/mcf5206.c                        |  2 +-
 hw/m68k/mcf5208.c                        | 10 +++---
 hw/m68k/mcf_intc.c                       |  2 +-
 hw/mem/pc-dimm.c                         |  2 +-
 hw/microblaze/petalogix_ml605_mmu.c      |  6 ++--
 hw/microblaze/petalogix_s3adsp1800_mmu.c |  5 +--
 hw/mips/gt64xxx_pci.c                    |  9 ++---
 hw/mips/mips_fulong2e.c                  |  5 +--
 hw/mips/mips_jazz.c                      | 30 ++++++++++------
 hw/mips/mips_malta.c                     | 17 +++++----
 hw/mips/mips_mipssim.c                   | 11 +++---
 hw/mips/mips_r4k.c                       | 14 +++++---
 hw/misc/debugexit.c                      |  2 +-
 hw/misc/ivshmem.c                        |  4 +--
 hw/misc/macio/macio.c                    | 24 +++++++------
 hw/misc/omap_gpmc.c                      |  7 ++--
 hw/misc/omap_l4.c                        |  3 +-
 hw/misc/omap_sdrc.c                      |  2 +-
 hw/misc/pc-testdev.c                     | 11 +++---
 hw/moxie/moxiesim.c                      |  4 +--
 hw/net/fsl_etsec/etsec.c                 |  3 +-
 hw/net/mcf_fec.c                         |  2 +-
 hw/openrisc/openrisc_sim.c               |  6 ++--
 hw/pci-host/apb.c                        |  3 +-
 hw/pci-host/grackle.c                    |  2 +-
 hw/pci-host/piix.c                       |  3 +-
 hw/pci-host/ppce500.c                    | 13 ++++---
 hw/pci-host/prep.c                       | 24 ++++++++-----
 hw/pci-host/q35.c                        |  8 +++--
 hw/pci-host/uninorth.c                   |  4 +--
 hw/pci/msix.c                            |  6 ++--
 hw/pci/pcie_host.c                       |  3 +-
 hw/pci/shpc.c                            |  2 +-
 hw/pcmcia/pxa2xx.c                       |  6 ++--
 hw/ppc/e500.c                            | 14 ++++----
 hw/ppc/mac_newworld.c                    | 14 +++++---
 hw/ppc/mac_oldworld.c                    |  6 ++--
 hw/ppc/ppc405_boards.c                   | 12 ++++---
 hw/ppc/ppc405_uc.c                       | 16 +++++----
 hw/ppc/ppc440_bamboo.c                   |  3 +-
 hw/ppc/ppc4xx_devs.c                     |  4 +--
 hw/ppc/ppc4xx_pci.c                      |  9 +++--
 hw/ppc/prep.c                            |  4 +--
 hw/ppc/spapr.c                           |  4 +--
 hw/ppc/spapr_pci.c                       |  8 ++---
 hw/ppc/spapr_pci_vfio.c                  |  2 +-
 hw/ppc/virtex_ml507.c                    |  3 +-
 hw/s390x/s390-virtio-ccw.c               |  2 +-
 hw/s390x/s390-virtio.c                   |  2 +-
 hw/s390x/sclp.c                          |  3 +-
 hw/sd/omap_mmc.c                         |  2 +-
 hw/sd/pxa2xx_mmci.c                      |  2 +-
 hw/sh4/r2d.c                             |  5 +--
 hw/sh4/sh7750.c                          | 21 ++++++++----
 hw/sh4/sh_pci.c                          |  6 ++--
 hw/sh4/shix.c                            |  6 ++--
 hw/sparc/leon3.c                         |  6 ++--
 hw/sparc64/sun4u.c                       |  2 +-
 hw/timer/m48t59.c                        |  3 +-
 hw/timer/sh_timer.c                      |  6 ++--
 hw/tpm/tpm_tis.c                         |  2 +-
 hw/tricore/tricore_testboard.c           | 12 +++----
 hw/unicore32/puv3.c                      |  6 ++--
 hw/usb/hcd-ehci-sysbus.c                 |  2 +-
 hw/usb/hcd-ehci.c                        |  8 +++--
 hw/usb/hcd-xhci.c                        | 15 +++++---
 hw/vfio/common.c                         |  2 +-
 hw/vfio/pci.c                            |  6 ++--
 hw/virtio/virtio-pci.c                   |  3 +-
 hw/xtensa/sim.c                          |  5 +--
 hw/xtensa/xtfpga.c                       | 18 +++++-----
 include/exec/memory.h                    |  3 +-
 ioport.c                                 |  2 +-
 memory.c                                 |  9 ++---
 numa.c                                   |  2 +-
 156 files changed, 619 insertions(+), 420 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index fe6215a..4269240 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -465,7 +465,7 @@ void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
     ar->pm1.evt.update_sci = update_sci;
     memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent),
                           &acpi_pm_evt_ops, ar, "acpi-evt", 4);
-    memory_region_add_subregion(parent, 0, &ar->pm1.evt.io);
+    memory_region_add_subregion(parent, 0, &ar->pm1.evt.io, &error_abort);
 }
 
 /* ACPI PM_TMR */
@@ -529,7 +529,7 @@ void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
     memory_region_init_io(&ar->tmr.io, memory_region_owner(parent),
                           &acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
     memory_region_clear_global_locking(&ar->tmr.io);
-    memory_region_add_subregion(parent, 8, &ar->tmr.io);
+    memory_region_add_subregion(parent, 8, &ar->tmr.io, &error_abort);
 }
 
 void acpi_pm_tmr_reset(ACPIREGS *ar)
@@ -604,7 +604,7 @@ void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
     qemu_register_wakeup_notifier(&ar->wakeup);
     memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent),
                           &acpi_pm_cnt_ops, ar, "acpi-cnt", 2);
-    memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io);
+    memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io, &error_abort);
 
     fw_cfg = fw_cfg_find();
     if (fw_cfg) {
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index f5b9972..7678fec 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -72,5 +72,5 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
     }
     memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
                           gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
-    memory_region_add_subregion(parent, base, &gpe_cpu->io);
+    memory_region_add_subregion(parent, base, &gpe_cpu->io, &error_abort);
 }
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index f4dc7a8..daf5a28 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -215,7 +215,7 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, bool smm_enabled,
     memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE);
     memory_region_set_enabled(&pm->io, false);
     memory_region_add_subregion(pci_address_space_io(lpc_pci),
-                                0, &pm->io);
+                                0, &pm->io, &error_abort);
 
     acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
     acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
@@ -225,11 +225,13 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, bool smm_enabled,
     acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
     memory_region_init_io(&pm->io_gpe, OBJECT(lpc_pci), &ich9_gpe_ops, pm,
                           "acpi-gpe0", ICH9_PMIO_GPE0_LEN);
-    memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe);
+    memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe,
+                                &error_abort);
 
     memory_region_init_io(&pm->io_smi, OBJECT(lpc_pci), &ich9_smi_ops, pm,
                           "acpi-smi", 8);
-    memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
+    memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi,
+                                &error_abort);
 
     pm->smm_enabled = smm_enabled;
     pm->irq = sci_irq;
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 2ff0d5c..81695cc 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -188,7 +188,8 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
     state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
     memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state,
                           "acpi-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN);
-    memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io);
+    memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io,
+                                &error_abort);
 }
 
 /**
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index fbbc4dd..e1b804a 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -314,7 +314,8 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
 
     memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
                           "acpi-pci-hotplug", s->io_len);
-    memory_region_add_subregion(address_space_io, s->io_base, &s->io);
+    memory_region_add_subregion(address_space_io, s->io_base, &s->io,
+                                &error_abort);
 
     object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
                                    &error_abort);
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 2cd2fee..634986c 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -467,12 +467,12 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
     pm_smbus_init(DEVICE(dev), &s->smb);
     memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1);
     memory_region_add_subregion(pci_address_space_io(dev),
-                                s->smb_io_base, &s->smb.io);
+                                s->smb_io_base, &s->smb.io, &error_abort);
 
     memory_region_init(&s->io, OBJECT(s), "piix4-pm", 64);
     memory_region_set_enabled(&s->io, false);
     memory_region_add_subregion(pci_address_space_io(dev),
-                                0, &s->io);
+                                0, &s->io, &error_abort);
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
@@ -563,7 +563,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
 {
     memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s,
                           "acpi-gpe0", GPE_LEN);
-    memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
+    memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe, &error_abort);
 
     acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent,
                     s->use_acpi_pci_hotplug);
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 421162e..4881491 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -847,7 +847,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
        but the address space hole reserved at this point is 8TB.  */
     memory_region_allocate_system_memory(&s->ram_region, OBJECT(s), "ram",
                                          ram_size);
-    memory_region_add_subregion(addr_space, 0, &s->ram_region);
+    memory_region_add_subregion(addr_space, 0, &s->ram_region, &error_abort);
 
     /* TIGbus, 0x801.0000.0000, 1GB.  */
     /* ??? The TIGbus is used for delivering interrupts, and access to
@@ -857,30 +857,30 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
     memory_region_init_io(&s->pchip.region, OBJECT(s), &pchip_ops, s, "pchip0",
                           256*MB);
     memory_region_add_subregion(addr_space, 0x80180000000ULL,
-                                &s->pchip.region);
+                                &s->pchip.region, &error_abort);
 
     /* Cchip CSRs, 0x801.A000.0000, 256MB.  */
     memory_region_init_io(&s->cchip.region, OBJECT(s), &cchip_ops, s, "cchip0",
                           256*MB);
     memory_region_add_subregion(addr_space, 0x801a0000000ULL,
-                                &s->cchip.region);
+                                &s->cchip.region, &error_abort);
 
     /* Dchip CSRs, 0x801.B000.0000, 256MB.  */
     memory_region_init_io(&s->dchip_region, OBJECT(s), &dchip_ops, s, "dchip0",
                           256*MB);
     memory_region_add_subregion(addr_space, 0x801b0000000ULL,
-                                &s->dchip_region);
+                                &s->dchip_region, &error_abort);
 
     /* Pchip0 PCI memory, 0x800.0000.0000, 4GB.  */
     memory_region_init(&s->pchip.reg_mem, OBJECT(s), "pci0-mem", 4*GB);
     memory_region_add_subregion(addr_space, 0x80000000000ULL,
-                                &s->pchip.reg_mem);
+                                &s->pchip.reg_mem, &error_abort);
 
     /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB.  */
     memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_ignore_ops,
                           NULL, "pci0-io", 32*MB);
     memory_region_add_subregion(addr_space, 0x801fc000000ULL,
-                                &s->pchip.reg_io);
+                                &s->pchip.reg_io, &error_abort);
 
     b = pci_register_bus(dev, "pci",
                          typhoon_set_irq, sys_map_irq, s,
@@ -898,13 +898,13 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
     memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
                           b, "pci0-iack", 64*MB);
     memory_region_add_subregion(addr_space, 0x801f8000000ULL,
-                                &s->pchip.reg_iack);
+                                &s->pchip.reg_iack, &error_abort);
 
     /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB.  */
     memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops,
                           b, "pci0-conf", 16*MB);
     memory_region_add_subregion(addr_space, 0x801fe000000ULL,
-                                &s->pchip.reg_conf);
+                                &s->pchip.reg_conf, &error_abort);
 
     /* For the record, these are the mappings for the second PCI bus.
        We can get away with not implementing them because we indicate
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index c6eab6d..e4739fb 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -231,7 +231,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
        when returning from an exception.  */
     memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000, &error_abort);
     vmstate_register_ram_global(hack);
-    memory_region_add_subregion(system_memory, 0xfffff000, hack);
+    memory_region_add_subregion(system_memory, 0xfffff000, hack, &error_abort);
 
     qemu_register_reset(armv7m_reset, cpu);
     return pic;
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index 1582250..d02bdfa 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -66,7 +66,7 @@ static void cubieboard_init(MachineState *machine)
     memory_region_allocate_system_memory(&s->sdram, NULL, "cubieboard.ram",
                                          machine->ram_size);
     memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
-                                &s->sdram);
+                                &s->sdram, &error_abort);
 
     cubieboard_binfo.ram_size = machine->ram_size;
     cubieboard_binfo.kernel_filename = machine->kernel_filename;
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index f8ba9e5..7d212d7 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -52,7 +52,7 @@ typedef struct DigicBoard {
 static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size)
 {
     memory_region_allocate_system_memory(&s->ram, NULL, "ram", ram_size);
-    memory_region_add_subregion(get_system_memory(), 0, &s->ram);
+    memory_region_add_subregion(get_system_memory(), 0, &s->ram, &error_abort);
 }
 
 static void digic4_board_init(DigicBoard *board)
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index c55fab8..d9f01cf 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -255,7 +255,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
     memory_region_init_io(&s->chipid_mem, NULL, &exynos4210_chipid_and_omr_ops,
         NULL, "exynos4210.chipid", sizeof(chipid_and_omr));
     memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
-                                &s->chipid_mem);
+                                &s->chipid_mem, &error_abort);
 
     /* Internal ROM */
     memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom",
@@ -263,7 +263,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
     vmstate_register_ram_global(&s->irom_mem);
     memory_region_set_readonly(&s->irom_mem, true);
     memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
-                                &s->irom_mem);
+                                &s->irom_mem, &error_abort);
     /* mirror of iROM */
     memory_region_init_alias(&s->irom_alias_mem, NULL, "exynos4210.irom_alias",
                              &s->irom_mem,
@@ -271,14 +271,14 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
                              EXYNOS4210_IROM_SIZE);
     memory_region_set_readonly(&s->irom_alias_mem, true);
     memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
-                                &s->irom_alias_mem);
+                                &s->irom_alias_mem, &error_abort);
 
     /* Internal RAM */
     memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
                            EXYNOS4210_IRAM_SIZE, &error_abort);
     vmstate_register_ram_global(&s->iram_mem);
     memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
-                                &s->iram_mem);
+                                &s->iram_mem, &error_abort);
 
     /* DRAM */
     mem_size = ram_size;
@@ -287,14 +287,14 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
                 mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_abort);
         vmstate_register_ram_global(&s->dram1_mem);
         memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
-                &s->dram1_mem);
+                &s->dram1_mem, &error_abort);
         mem_size = EXYNOS4210_DRAM_MAX_SIZE;
     }
     memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
                            &error_abort);
     vmstate_register_ram_global(&s->dram0_mem);
     memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
-            &s->dram0_mem);
+            &s->dram0_mem, &error_abort);
 
    /* PMU.
     * The only reason of existence at the moment is that secondary CPU boot
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index f8353a7..aff14d5 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -277,12 +277,12 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
     dram = g_new(MemoryRegion, 1);
     memory_region_allocate_system_memory(dram, NULL, "highbank.dram", ram_size);
     /* SDRAM at address zero.  */
-    memory_region_add_subregion(sysmem, 0, dram);
+    memory_region_add_subregion(sysmem, 0, dram, &error_abort);
 
     sysram = g_new(MemoryRegion, 1);
     memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000,
                            &error_abort);
-    memory_region_add_subregion(sysmem, 0xfff88000, sysram);
+    memory_region_add_subregion(sysmem, 0xfff88000, sysram, &error_abort);
     if (bios_name != NULL) {
         sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (sysboot_filename != NULL) {
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 0fbbf99..5a2094e 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -572,10 +572,11 @@ static void integratorcp_init(MachineState *machine)
     /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
     /* ??? RAM should repeat to fill physical memory space.  */
     /* SDRAM at address zero*/
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
     /* And again at address 0x80000000 */
     memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
-    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
+    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias,
+                                &error_abort);
 
     dev = qdev_create(NULL, TYPE_INTEGRATOR_CM);
     qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 5be0369..5999585 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -98,13 +98,16 @@ static void kzm_init(MachineState *machine)
     /* On a real system, the first 16k is a `secure boot rom' */
 
     memory_region_allocate_system_memory(ram, NULL, "kzm.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
+    memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram,
+                                &error_abort);
 
     memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
-    memory_region_add_subregion(address_space_mem, 0x88000000, ram_alias);
+    memory_region_add_subregion(address_space_mem, 0x88000000, ram_alias,
+                                &error_abort);
 
     memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000, &error_abort);
-    memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
+    memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram,
+                                &error_abort);
 
     dev = sysbus_create_varargs("imx_avic", 0x68000000,
                                 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 0da02a6..49850d5 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -127,7 +127,7 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
                            &error_abort);
     vmstate_register_ram_global(rom);
     memory_region_set_readonly(rom, true);
-    memory_region_add_subregion(address_space_mem, 0, rom);
+    memory_region_add_subregion(address_space_mem, 0, rom, &error_abort);
 
 #ifdef TARGET_WORDS_BIGENDIAN
     be = 1;
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index a3b1314..2456767 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1602,12 +1602,13 @@ static void musicpal_init(MachineState *machine)
     /* For now we use a fixed - the original - RAM size */
     memory_region_allocate_system_memory(ram, NULL, "musicpal.ram",
                                          MP_RAM_DEFAULT_SIZE);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
 
     memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE,
                            &error_abort);
     vmstate_register_ram_global(sram);
-    memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
+    memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram,
+                                &error_abort);
 
     dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index de2b289..8014014 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -271,7 +271,7 @@ static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
     memory_region_init_io(&s->iomem, NULL, &omap_mpu_timer_ops, s,
                           "omap-mpu-timer", 0x100);
 
-    memory_region_add_subregion(system_memory, base, &s->iomem);
+    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
 
     return s;
 }
@@ -399,7 +399,7 @@ static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
 
     memory_region_init_io(&s->iomem, NULL, &omap_wd_timer_ops, s,
                           "omap-wd-timer", 0x100);
-    memory_region_add_subregion(memory, base, &s->iomem);
+    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
 
     return s;
 }
@@ -506,7 +506,7 @@ static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
 
     memory_region_init_io(&s->iomem, NULL, &omap_os_timer_ops, s,
                           "omap-os-timer", 0x800);
-    memory_region_add_subregion(memory, base, &s->iomem);
+    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
 
     return s;
 }
@@ -740,7 +740,8 @@ static void omap_ulpd_pm_init(MemoryRegion *system_memory,
 {
     memory_region_init_io(&mpu->ulpd_pm_iomem, NULL, &omap_ulpd_pm_ops, mpu,
                           "omap-ulpd-pm", 0x800);
-    memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
+    memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem,
+                                &error_abort);
     omap_ulpd_pm_reset(mpu);
 }
 
@@ -963,7 +964,8 @@ static void omap_pin_cfg_init(MemoryRegion *system_memory,
 {
     memory_region_init_io(&mpu->pin_cfg_iomem, NULL, &omap_pin_cfg_ops, mpu,
                           "omap-pin-cfg", 0x800);
-    memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
+    memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem,
+                                &error_abort);
     omap_pin_cfg_reset(mpu);
 }
 
@@ -1038,14 +1040,17 @@ static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
                           "omap-id", 0x100000000ULL);
     memory_region_init_alias(&mpu->id_iomem_e18, NULL, "omap-id-e18", &mpu->id_iomem,
                              0xfffe1800, 0x800);
-    memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
+    memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18,
+                                &error_abort);
     memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-ed4", &mpu->id_iomem,
                              0xfffed400, 0x100);
-    memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
+    memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4,
+                                &error_abort);
     if (!cpu_is_omap15xx(mpu)) {
         memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-e20",
                                  &mpu->id_iomem, 0xfffe2000, 0x800);
-        memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
+        memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20,
+                                    &error_abort);
     }
 }
 
@@ -1131,7 +1136,7 @@ static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
 {
     memory_region_init_io(&mpu->mpui_iomem, NULL, &omap_mpui_ops, mpu,
                           "omap-mpui", 0x100);
-    memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
+    memory_region_add_subregion(memory, base, &mpu->mpui_iomem, &error_abort);
 
     omap_mpui_reset(mpu);
 }
@@ -1244,7 +1249,7 @@ static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
 
     memory_region_init_io(&s->iomem, NULL, &omap_tipb_bridge_ops, s,
                           "omap-tipb-bridge", 0x100);
-    memory_region_add_subregion(memory, base, &s->iomem);
+    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
 
     return s;
 }
@@ -1354,7 +1359,7 @@ static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
 {
     memory_region_init_io(&mpu->tcmi_iomem, NULL, &omap_tcmi_ops, mpu,
                           "omap-tcmi", 0x100);
-    memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
+    memory_region_add_subregion(memory, base, &mpu->tcmi_iomem, &error_abort);
     omap_tcmi_reset(mpu);
 }
 
@@ -1440,7 +1445,7 @@ static struct dpll_ctl_s  *omap_dpll_init(MemoryRegion *memory,
     s->dpll = clk;
     omap_dpll_reset(s);
 
-    memory_region_add_subregion(memory, base, &s->iomem);
+    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
     return s;
 }
 
@@ -1861,8 +1866,9 @@ static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
     omap_clkm_reset(s);
     s->clkm.cold_start = 0x3a;
 
-    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
-    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
+    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem, &error_abort);
+    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem,
+                                &error_abort);
 }
 
 /* MPU I/O */
@@ -2110,7 +2116,7 @@ static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
 
     memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s,
                           "omap-mpuio", 0x800);
-    memory_region_add_subregion(memory, base, &s->iomem);
+    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
 
     omap_clk_adduser(clk, qemu_allocate_irq(omap_mpuio_onoff, s, 0));
 
@@ -2301,7 +2307,7 @@ static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
     omap_uwire_reset(s);
 
     memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800);
-    memory_region_add_subregion(system_memory, base, &s->iomem);
+    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
 
     return s;
 }
@@ -2415,7 +2421,7 @@ static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
 
     memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s,
                           "omap-pwl", 0x800);
-    memory_region_add_subregion(system_memory, base, &s->iomem);
+    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
 
     omap_clk_adduser(clk, qemu_allocate_irq(omap_pwl_clk_update, s, 0));
     return s;
@@ -2523,7 +2529,7 @@ static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
 
     memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s,
                           "omap-pwt", 0x800);
-    memory_region_add_subregion(system_memory, base, &s->iomem);
+    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
     return s;
 }
 
@@ -2943,7 +2949,7 @@ static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
 
     memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,
                           "omap-rtc", 0x800);
-    memory_region_add_subregion(system_memory, base, &s->iomem);
+    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
 
     return s;
 }
@@ -3480,7 +3486,7 @@ static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
     omap_mcbsp_reset(s);
 
     memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
-    memory_region_add_subregion(system_memory, base, &s->iomem);
+    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
 
     return s;
 }
@@ -3656,7 +3662,7 @@ static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
     omap_lpg_reset(s);
 
     memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800);
-    memory_region_add_subregion(system_memory, base, &s->iomem);
+    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
 
     omap_clk_adduser(clk, qemu_allocate_irq(omap_lpg_clk_update, s, 0));
 
@@ -3697,7 +3703,7 @@ static void omap_setup_mpui_io(MemoryRegion *system_memory,
     memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu,
                           "omap-mpui-io", 0x7fff);
     memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
-                                &mpu->mpui_io_iomem);
+                                &mpu->mpui_io_iomem, &error_abort);
 }
 
 /* General chip reset */
@@ -3777,7 +3783,8 @@ static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
         io = g_new(MemoryRegion, 1);
         memory_region_init_alias(io, NULL, map->name,
                                  system_memory, map->phys_mpu, map->size);
-        memory_region_add_subregion(system_memory, map->phys_dsp, io);
+        memory_region_add_subregion(system_memory, map->phys_dsp, io,
+                                    &error_abort);
     }
 }
 
@@ -3880,11 +3887,13 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
     /* Memory-mapped stuff */
     memory_region_allocate_system_memory(&s->emiff_ram, NULL, "omap1.dram",
                                          s->sdram_size);
-    memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
+    memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram,
+                                &error_abort);
     memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
                            &error_abort);
     vmstate_register_ram_global(&s->imif_ram);
-    memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
+    memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram,
+                                &error_abort);
 
     omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
 
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index e39b317..6d70831 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -802,7 +802,8 @@ static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
 
     memory_region_init_io(&s->iomem_fifo, NULL, &omap_sti_fifo_ops, s,
                           "omap.sti.fifo", 0x10000);
-    memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo);
+    memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo,
+                                &error_abort);
 
     return s;
 }
@@ -2274,11 +2275,12 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
     /* Memory-mapped stuff */
     memory_region_allocate_system_memory(&s->sdram, NULL, "omap2.dram",
                                          s->sdram_size);
-    memory_region_add_subregion(sysmem, OMAP2_Q2_BASE, &s->sdram);
+    memory_region_add_subregion(sysmem, OMAP2_Q2_BASE, &s->sdram, &error_abort);
     memory_region_init_ram(&s->sram, NULL, "omap2.sram", s->sram_size,
                            &error_abort);
     vmstate_register_ram_global(&s->sram);
-    memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram);
+    memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram,
+                                &error_abort);
 
     s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
 
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 4b0f7f9..93be711 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -125,23 +125,25 @@ static void sx1_init(MachineState *machine, const int version)
                            &error_abort);
     vmstate_register_ram_global(flash);
     memory_region_set_readonly(flash, true);
-    memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash);
+    memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash,
+                                &error_abort);
 
     memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val,
                           "sx1.cs0", OMAP_CS0_SIZE - flash_size);
     memory_region_add_subregion(address_space,
-                                OMAP_CS0_BASE + flash_size, &cs[0]);
+                                OMAP_CS0_BASE + flash_size, &cs[0],
+                                &error_abort);
 
 
     memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val,
                           "sx1.cs2", OMAP_CS2_SIZE);
     memory_region_add_subregion(address_space,
-                                OMAP_CS2_BASE, &cs[2]);
+                                OMAP_CS2_BASE, &cs[2], &error_abort);
 
     memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val,
                           "sx1.cs3", OMAP_CS3_SIZE);
     memory_region_add_subregion(address_space,
-                                OMAP_CS2_BASE, &cs[3]);
+                                OMAP_CS2_BASE, &cs[3], &error_abort);
 
     fl_idx = 0;
 #ifdef TARGET_WORDS_BIGENDIAN
@@ -169,12 +171,14 @@ static void sx1_init(MachineState *machine, const int version)
                                &error_abort);
         vmstate_register_ram_global(flash_1);
         memory_region_set_readonly(flash_1, true);
-        memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1);
+        memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1,
+                                    &error_abort);
 
         memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
                               "sx1.cs1", OMAP_CS1_SIZE - flash1_size);
         memory_region_add_subregion(address_space,
-                                OMAP_CS1_BASE + flash1_size, &cs[1]);
+                                OMAP_CS1_BASE + flash1_size, &cs[1],
+                                &error_abort);
 
         if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
                                    "omap_sx1.flash1-1", flash1_size,
@@ -189,7 +193,8 @@ static void sx1_init(MachineState *machine, const int version)
         memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
                               "sx1.cs1", OMAP_CS1_SIZE);
         memory_region_add_subregion(address_space,
-                                OMAP_CS1_BASE, &cs[1]);
+                                OMAP_CS1_BASE, &cs[1],
+                                &error_abort);
     }
 
     if (!machine->kernel_filename && !fl_idx && !qtest_enabled()) {
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index 7f1cfb8..7b34ba4 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -216,21 +216,25 @@ static void palmte_init(MachineState *machine)
                            &error_abort);
     vmstate_register_ram_global(flash);
     memory_region_set_readonly(flash, true);
-    memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);
+    memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash,
+                                &error_abort);
 
     memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val, "palmte-cs0",
                           OMAP_CS0_SIZE - flash_size);
     memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size,
-                                &cs[0]);
+                                &cs[0], &error_abort);
     memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val, "palmte-cs1",
                           OMAP_CS1_SIZE);
-    memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]);
+    memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1],
+                                &error_abort);
     memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val, "palmte-cs2",
                           OMAP_CS2_SIZE);
-    memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]);
+    memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2],
+                                &error_abort);
     memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val, "palmte-cs3",
                           OMAP_CS3_SIZE);
-    memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]);
+    memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3],
+                                &error_abort);
 
     palmte_microwire_setup(mpu);
 
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index ec353f7..8c38a57 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1743,7 +1743,7 @@ static PXA2xxI2SState *pxa2xx_i2s_init(MemoryRegion *sysmem,
 
     memory_region_init_io(&s->iomem, NULL, &pxa2xx_i2s_ops, s,
                           "pxa2xx-i2s", 0x100000);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s);
 
@@ -2081,12 +2081,13 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
     memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size,
                            &error_abort);
     vmstate_register_ram_global(&s->sdram);
-    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
+    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram,
+                                &error_abort);
     memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000,
                            &error_abort);
     vmstate_register_ram_global(&s->internal);
     memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
-                                &s->internal);
+                                &s->internal, &error_abort);
 
     s->pic = pxa2xx_pic_init(0x40d00000, s->cpu);
 
@@ -2138,7 +2139,8 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
     s->cm_regs[CCCR >> 2] = 0x02000210;	/* 416.0 MHz */
     s->clkcfg = 0x00000009;		/* Turbo mode active */
     memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
-    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
+    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem,
+                                &error_abort);
     vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
 
     pxa2xx_setup_cp14(s);
@@ -2148,12 +2150,14 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
     s->mm_regs[MDREFR >> 2] = 0x03ca4000;
     s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */
     memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);
-    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);
+    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem,
+                                &error_abort);
     vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
 
     s->pm_base = 0x40f00000;
     memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);
-    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);
+    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem,
+                                &error_abort);
     vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
 
     for (i = 0; pxa27x_ssp[i].io_base; i ++);
@@ -2215,12 +2219,13 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
     memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size,
                            &error_abort);
     vmstate_register_ram_global(&s->sdram);
-    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
+    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram,
+                                &error_abort);
     memory_region_init_ram(&s->internal, NULL, "pxa255.internal",
                            PXA2XX_INTERNAL_SIZE, &error_abort);
     vmstate_register_ram_global(&s->internal);
     memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
-                                &s->internal);
+                                &s->internal, &error_abort);
 
     s->pic = pxa2xx_pic_init(0x40d00000, s->cpu);
 
@@ -2271,7 +2276,8 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
     s->cm_regs[CCCR >> 2] = 0x02000210;	/* 416.0 MHz */
     s->clkcfg = 0x00000009;		/* Turbo mode active */
     memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
-    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
+    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem,
+                                &error_abort);
     vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
 
     pxa2xx_setup_cp14(s);
@@ -2281,12 +2287,14 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
     s->mm_regs[MDREFR >> 2] = 0x03ca4000;
     s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */
     memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);
-    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);
+    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem,
+                                &error_abort);
     vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
 
     s->pm_base = 0x40f00000;
     memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);
-    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);
+    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem,
+                                &error_abort);
     vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
 
     for (i = 0; pxa255_ssp[i].io_base; i ++);
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index ef2788d..b16c8ae 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -153,7 +153,7 @@ static void realview_init(MachineState *machine,
         memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size,
                                &error_abort);
         vmstate_register_ram_global(ram_lo);
-        memory_region_add_subregion(sysmem, 0x20000000, ram_lo);
+        memory_region_add_subregion(sysmem, 0x20000000, ram_lo, &error_abort);
     }
 
     memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size,
@@ -165,10 +165,10 @@ static void realview_init(MachineState *machine,
     /* SDRAM at address zero.  */
     memory_region_init_alias(ram_alias, NULL, "realview.alias",
                              ram_hi, 0, low_ram_size);
-    memory_region_add_subregion(sysmem, 0, ram_alias);
+    memory_region_add_subregion(sysmem, 0, ram_alias, &error_abort);
     if (is_pb) {
         /* And again at a high address.  */
-        memory_region_add_subregion(sysmem, 0x70000000, ram_hi);
+        memory_region_add_subregion(sysmem, 0x70000000, ram_hi, &error_abort);
     } else {
         ram_size = low_ram_size;
     }
@@ -355,7 +355,7 @@ static void realview_init(MachineState *machine,
     memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000,
                            &error_abort);
     vmstate_register_ram_global(ram_hack);
-    memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack);
+    memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack, &error_abort);
 
     realview_binfo.ram_size = ram_size;
     realview_binfo.kernel_filename = machine->kernel_filename;
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 5bf032a..5e6ac91 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -916,7 +916,7 @@ static void spitz_common_init(MachineState *machine,
     memory_region_init_ram(rom, NULL, "spitz.rom", SPITZ_ROM, &error_abort);
     vmstate_register_ram_global(rom);
     memory_region_set_readonly(rom, true);
-    memory_region_add_subregion(address_space_mem, 0, rom);
+    memory_region_add_subregion(address_space_mem, 0, rom, &error_abort);
 
     /* Setup peripherals */
     spitz_keyboard_register(mpu);
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index cb515ec..51c3bb9 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -683,7 +683,8 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
     s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
 
     memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
-    memory_region_add_subregion(get_system_memory(), base, &s->iomem);
+    memory_region_add_subregion(get_system_memory(), base, &s->iomem,
+                                &error_abort);
     ssys_reset(s);
     vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
     return 0;
@@ -1234,12 +1235,12 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
                            &error_abort);
     vmstate_register_ram_global(flash);
     memory_region_set_readonly(flash, true);
-    memory_region_add_subregion(system_memory, 0, flash);
+    memory_region_add_subregion(system_memory, 0, flash, &error_abort);
 
     memory_region_init_ram(sram, NULL, "stellaris.sram", sram_size,
                            &error_abort);
     vmstate_register_ram_global(sram);
-    memory_region_add_subregion(system_memory, 0x20000000, sram);
+    memory_region_add_subregion(system_memory, 0x20000000, sram, &error_abort);
 
     pic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
                       kernel_filename, cpu_model);
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index 0f3bdc7..996538f 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -80,13 +80,15 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
     memory_region_set_readonly(flash, true);
     memory_region_set_readonly(flash_alias, true);
 
-    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);
-    memory_region_add_subregion(system_memory, 0, flash_alias);
+    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash,
+                                &error_abort);
+    memory_region_add_subregion(system_memory, 0, flash_alias, &error_abort);
 
     memory_region_init_ram(sram, NULL, "STM32F205.sram", SRAM_SIZE,
                            &error_abort);
     vmstate_register_ram_global(sram);
-    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
+    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram,
+                                &error_abort);
 
     pic = armv7m_init(get_system_memory(), FLASH_SIZE, 96,
                       s->kernel_filename, s->cpu_model);
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index da9fc1d..7b2b970 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1608,7 +1608,7 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
 
     memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram",
                                          sdram_size);
-    memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
+    memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram, &error_abort);
 
     s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
                     qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 73572eb..bc56ae0 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -230,7 +230,7 @@ static void tosa_init(MachineState *machine)
     memory_region_init_ram(rom, NULL, "tosa.rom", TOSA_ROM, &error_abort);
     vmstate_register_ram_global(rom);
     memory_region_set_readonly(rom, true);
-    memory_region_add_subregion(address_space_mem, 0, rom);
+    memory_region_add_subregion(address_space_mem, 0, rom, &error_abort);
 
     tmio = tc6393xb_init(address_space_mem, 0x10000000,
             qdev_get_gpio_in(mpu->gpio, TOSA_GPIO_TC6393XB_INT));
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 6c69f4e..82358eb 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -230,7 +230,7 @@ static void versatile_init(MachineState *machine, int board_id)
                                          machine->ram_size);
     /* ??? RAM should repeat to fill physical memory space.  */
     /* SDRAM at address zero.  */
-    memory_region_add_subregion(sysmem, 0, ram);
+    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
 
     sysctl = qdev_create(NULL, "realview_sysctl");
     qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004);
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index da21788..20cd79b 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -289,8 +289,8 @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
      * things including ROM or RAM; we always map the RAM there.
      */
     memory_region_init_alias(lowram, NULL, "vexpress.lowmem", ram, 0, low_ram_size);
-    memory_region_add_subregion(sysmem, 0x0, lowram);
-    memory_region_add_subregion(sysmem, 0x60000000, ram);
+    memory_region_add_subregion(sysmem, 0x0, lowram, &error_abort);
+    memory_region_add_subregion(sysmem, 0x60000000, ram, &error_abort);
 
     /* 0x1e000000 A9MPCore (SCU) private memory region */
     init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic, vms->secure);
@@ -375,7 +375,7 @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
     memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
                                          ram_size);
     /* RAM is from 0x80000000 upwards; there is no low-memory alias for it. */
-    memory_region_add_subregion(sysmem, 0x80000000, ram);
+    memory_region_add_subregion(sysmem, 0x80000000, ram, &error_abort);
 
     /* 0x2c000000 A15MPCore private memory region (GIC) */
     init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic, vms->secure);
@@ -393,7 +393,7 @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
     memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000,
                            &error_abort);
     vmstate_register_ram_global(sram);
-    memory_region_add_subregion(sysmem, 0x2e000000, sram);
+    memory_region_add_subregion(sysmem, 0x2e000000, sram, &error_abort);
 
     /* 0x7ffb0000: DMA330 DMA controller: not modelled */
     /* 0x7ffd0000: PL354 static memory controller: not modelled */
@@ -659,7 +659,8 @@ static void vexpress_common_init(MachineState *machine)
         flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0);
         memory_region_init_alias(flashalias, NULL, "vexpress.flashalias",
                                  flash0mem, 0, VEXPRESS_FLASH_SIZE);
-        memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias);
+        memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias,
+                                    &error_abort);
     }
 
     dinfo = drive_get_next(IF_PFLASH);
@@ -673,13 +674,13 @@ static void vexpress_common_init(MachineState *machine)
     memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
                            &error_abort);
     vmstate_register_ram_global(sram);
-    memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
+    memory_region_add_subregion(sysmem, map[VE_SRAM], sram, &error_abort);
 
     vram_size = 0x800000;
     memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
                            &error_abort);
     vmstate_register_ram_global(vram);
-    memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
+    memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram, &error_abort);
 
     /* 0x4e000000 LAN9118 Ethernet */
     if (nd_table[0].used) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4846892..8ed9c05 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -685,7 +685,8 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
     ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
     memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
                              ecam_reg, 0, size_ecam);
-    memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias);
+    memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias,
+                                &error_abort);
 
     /* Map the MMIO window into system address space so as to expose
      * the section of PCI MMIO space which starts at the same base address
@@ -696,7 +697,8 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
     mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
     memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
                              mmio_reg, base_mmio, size_mmio);
-    memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
+    memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias,
+                                &error_abort);
 
     /* Map IO port space */
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
@@ -769,7 +771,8 @@ static void create_platform_bus(VirtBoardInfo *vbi, qemu_irq *pic)
 
     memory_region_add_subregion(sysmem,
                                 platform_bus_params.platform_bus_base,
-                                sysbus_mmio_get_region(s, 0));
+                                sysbus_mmio_get_region(s, 0),
+                                &error_abort);
 }
 
 static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
@@ -871,7 +874,8 @@ static void machvirt_init(MachineState *machine)
 
     memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
                                          machine->ram_size);
-    memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
+    memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram,
+                                &error_abort);
 
     create_flash(vbi);
 
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index a4e7b5c..8cbce61 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -163,13 +163,14 @@ static void zynq_init(MachineState *machine)
     /* DDR remapped to address zero.  */
     memory_region_allocate_system_memory(ext_ram, NULL, "zynq.ext_ram",
                                          ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ext_ram);
+    memory_region_add_subregion(address_space_mem, 0, ext_ram, &error_abort);
 
     /* 256K of on-chip memory */
     memory_region_init_ram(ocm_ram, NULL, "zynq.ocm_ram", 256 << 10,
                            &error_abort);
     vmstate_register_ram_global(ocm_ram);
-    memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram);
+    memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram,
+                                &error_abort);
 
     DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
 
diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index f94da86..ab4dc21 100644
--- a/hw/arm/xlnx-ep108.c
+++ b/hw/arm/xlnx-ep108.c
@@ -58,7 +58,8 @@ static void xlnx_ep108_init(MachineState *machine)
 
     memory_region_allocate_system_memory(&s->ddr_ram, NULL, "ddr-ram",
                                          machine->ram_size);
-    memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram);
+    memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram,
+                                &error_abort);
 
     xlnx_ep108_binfo.ram_size = machine->ram_size;
     xlnx_ep108_binfo.kernel_filename = machine->kernel_filename;
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 5e72078..c6e6b0a 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -125,7 +125,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
             addr += XLNX_ZYNQMP_GIC_REGION_SIZE;
             memory_region_init_alias(alias, OBJECT(s), "zynqmp-gic-alias", mr,
                                      0, XLNX_ZYNQMP_GIC_REGION_SIZE);
-            memory_region_add_subregion(system_memory, addr, alias);
+            memory_region_add_subregion(system_memory, addr, alias,
+                                        &error_abort);
         }
     }
 
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index 1b2c893..d8a5897 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -120,7 +120,7 @@ static void onenand_mem_setup(OneNANDState *s)
      * write boot commands.  Also take note of the BWPS bit.  */
     memory_region_init(&s->container, OBJECT(s), "onenand",
                        0x10000 << s->shift);
-    memory_region_add_subregion(&s->container, 0, &s->iomem);
+    memory_region_add_subregion(&s->container, 0, &s->iomem, &error_abort);
     memory_region_init_alias(&s->mapped_ram, OBJECT(s), "onenand-mapped-ram",
                              &s->ram, 0x0200 << s->shift,
                              0xbe00 << s->shift);
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 074a005..100e07c 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -111,7 +111,8 @@ static void pflash_setup_mappings(pflash_t *pfl)
     for (i = 0; i < pfl->mappings; ++i) {
         memory_region_init_alias(&pfl->mem_mappings[i], OBJECT(pfl),
                                  "pflash-alias", &pfl->orig_mem, 0, size);
-        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
+        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i],
+                                    &error_abort);
     }
 }
 
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 36f1c4a..1c0a04d 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -106,7 +106,7 @@ static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)
     memory_region_init_io(&s->io, OBJECT(dev), &debugcon_ops, s,
                           TYPE_ISA_DEBUGCON_DEVICE, 1);
     memory_region_add_subregion(isa_address_space_io(d),
-                                isa->iobase, &s->io);
+                                isa->iobase, &s->io, &error_abort);
 }
 
 static Property debugcon_isa_properties[] = {
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index 98fd44e..ecb31a0 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -303,5 +303,5 @@ void mcf_uart_mm_init(MemoryRegion *sysmem,
 
     s = mcf_uart_init(irq, chr);
     memory_region_init_io(&s->iomem, NULL, &mcf_uart_ops, s, "uart", 0x40);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 }
diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
index 88f2094..1beb0f3 100644
--- a/hw/char/omap_uart.c
+++ b/hw/char/omap_uart.c
@@ -173,7 +173,7 @@ struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
 
     s->ta = ta;
 
-    memory_region_add_subregion(sysmem, base + 0x20, &s->iomem);
+    memory_region_add_subregion(sysmem, base + 0x20, &s->iomem, &error_abort);
 
     return s;
 }
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index c2b553f..72f4ef8 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -606,7 +606,7 @@ bool parallel_mm_init(MemoryRegion *address_space,
 
     memory_region_init_io(&s->iomem, NULL, &parallel_mm_ops, s,
                           "parallel", 8 << it_shift);
-    memory_region_add_subregion(address_space, base, &s->iomem);
+    memory_region_add_subregion(address_space, base, &s->iomem, &error_abort);
     return true;
 }
 
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index 1c8b9be..751979b 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -123,7 +123,7 @@ static void multi_serial_pci_realize(PCIDevice *dev, Error **errp)
         pci->name[i] = g_strdup_printf("uart #%d", i+1);
         memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s,
                               pci->name[i], 8);
-        memory_region_add_subregion(&pci->iobar, 8 * i, &s->io);
+        memory_region_add_subregion(&pci->iobar, 8 * i, &s->io, &error_abort);
         pci->ports++;
     }
 }
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 513d73c..a1cedca 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -904,7 +904,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
     vmstate_register(NULL, base, &vmstate_serial, s);
 
     memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8);
-    memory_region_add_subregion(system_io, base, &s->io);
+    memory_region_add_subregion(system_io, base, &s->io, &error_abort);
 
     return s;
 }
@@ -967,6 +967,6 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
 
     memory_region_init_io(&s->io, NULL, &serial_mm_ops[end], s,
                           "serial", 8 << it_shift);
-    memory_region_add_subregion(address_space, base, &s->io);
+    memory_region_add_subregion(address_space, base, &s->io, &error_abort);
     return s;
 }
diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
index 9328dd1..45dee7b 100644
--- a/hw/char/sh_serial.c
+++ b/hw/char/sh_serial.c
@@ -386,11 +386,13 @@ void sh_serial_init(MemoryRegion *sysmem,
 
     memory_region_init_alias(&s->iomem_p4, NULL, "serial-p4", &s->iomem,
                              0, 0x28);
-    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4);
+    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4,
+                                &error_abort);
 
     memory_region_init_alias(&s->iomem_a7, NULL, "serial-a7", &s->iomem,
                              0, 0x28);
-    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7);
+    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7,
+                                &error_abort);
 
     s->chr = chr;
 
diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c
index 70e0518..025af03 100644
--- a/hw/core/platform-bus.c
+++ b/hw/core/platform-bus.c
@@ -159,7 +159,7 @@ static int platform_bus_map_mmio(PlatformBusDevice *pbus, SysBusDevice *sbdev,
     }
 
     /* Map the device's region into our Platform Bus MMIO space */
-    memory_region_add_subregion(&pbus->mmio, off, sbdev_mr);
+    memory_region_add_subregion(&pbus->mmio, off, sbdev_mr, &error_abort);
 
     return 0;
 }
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 3c58629..d7d2dc3 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -147,7 +147,7 @@ static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr,
     else {
         memory_region_add_subregion(get_system_memory(),
                                     addr,
-                                    dev->mmio[n].memory);
+                                    dev->mmio[n].memory, &error_abort);
     }
 }
 
@@ -312,7 +312,7 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
 void sysbus_add_io(SysBusDevice *dev, hwaddr addr,
                        MemoryRegion *mem)
 {
-    memory_region_add_subregion(get_system_io(), addr, mem);
+    memory_region_add_subregion(get_system_io(), addr, mem, &error_abort);
 }
 
 MemoryRegion *sysbus_address_space(SysBusDevice *dev)
diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index acc419e..7f4d179 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -98,9 +98,11 @@ static void a15mp_priv_realize(DeviceState *dev, Error **errp)
      *  0x6000-0x7fff -- GIC virtual CPU interface (not modelled)
      */
     memory_region_add_subregion(&s->container, 0x1000,
-                                sysbus_mmio_get_region(busdev, 0));
+                                sysbus_mmio_get_region(busdev, 0),
+                                &error_abort);
     memory_region_add_subregion(&s->container, 0x2000,
-                                sysbus_mmio_get_region(busdev, 1));
+                                sysbus_mmio_get_region(busdev, 1),
+                                &error_abort);
 }
 
 static Property a15mp_priv_properties[] = {
diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index c09358c..bb63075 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -112,21 +112,27 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
      *  0x1000-0x1fff -- GIC Distributor
      */
     memory_region_add_subregion(&s->container, 0,
-                                sysbus_mmio_get_region(scubusdev, 0));
+                                sysbus_mmio_get_region(scubusdev, 0),
+                                &error_abort);
     /* GIC CPU interface */
     memory_region_add_subregion(&s->container, 0x100,
-                                sysbus_mmio_get_region(gicbusdev, 1));
+                                sysbus_mmio_get_region(gicbusdev, 1),
+                                &error_abort);
     memory_region_add_subregion(&s->container, 0x200,
-                                sysbus_mmio_get_region(gtimerbusdev, 0));
+                                sysbus_mmio_get_region(gtimerbusdev, 0),
+                                &error_abort);
     /* Note that the A9 exposes only the "timer/watchdog for this core"
      * memory region, not the "timer/watchdog for core X" ones 11MPcore has.
      */
     memory_region_add_subregion(&s->container, 0x600,
-                                sysbus_mmio_get_region(mptimerbusdev, 0));
+                                sysbus_mmio_get_region(mptimerbusdev, 0),
+                                &error_abort);
     memory_region_add_subregion(&s->container, 0x620,
-                                sysbus_mmio_get_region(wdtbusdev, 0));
+                                sysbus_mmio_get_region(wdtbusdev, 0),
+                                &error_abort);
     memory_region_add_subregion(&s->container, 0x1000,
-                                sysbus_mmio_get_region(gicbusdev, 0));
+                                sysbus_mmio_get_region(gicbusdev, 0),
+                                &error_abort);
 
     /* Wire up the interrupt from each watchdog and timer.
      * For each core the global timer is PPI 27, the private
diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index 717d3e4..987e7ec 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -28,14 +28,16 @@ static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
     SysBusDevice *wdtbusdev = SYS_BUS_DEVICE(&s->wdtimer);
 
     memory_region_add_subregion(&s->container, 0,
-                                sysbus_mmio_get_region(scubusdev, 0));
+                                sysbus_mmio_get_region(scubusdev, 0),
+                                &error_abort);
     /* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs
      * at 0x200, 0x300...
      */
     for (i = 0; i < (s->num_cpu + 1); i++) {
         hwaddr offset = 0x100 + (i * 0x100);
         memory_region_add_subregion(&s->container, offset,
-                                    sysbus_mmio_get_region(gicbusdev, i + 1));
+                                    sysbus_mmio_get_region(gicbusdev, i + 1),
+                                    &error_abort);
     }
     /* Add the regions for timer and watchdog for "current CPU" and
      * for each specific CPU.
@@ -44,12 +46,15 @@ static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
         /* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */
         hwaddr offset = 0x600 + i * 0x100;
         memory_region_add_subregion(&s->container, offset,
-                                    sysbus_mmio_get_region(timerbusdev, i));
+                                    sysbus_mmio_get_region(timerbusdev, i),
+                                    &error_abort);
         memory_region_add_subregion(&s->container, offset + 0x20,
-                                    sysbus_mmio_get_region(wdtbusdev, i));
+                                    sysbus_mmio_get_region(wdtbusdev, i),
+                                    &error_abort);
     }
     memory_region_add_subregion(&s->container, 0x1000,
-                                sysbus_mmio_get_region(gicbusdev, 0));
+                                sysbus_mmio_get_region(gicbusdev, 0),
+                                &error_abort);
     /* Wire up the interrupt from each watchdog and timer.
      * For each core the timer is PPI 29 and the watchdog PPI 30.
      */
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 3cae480..fbe6219 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -272,14 +272,16 @@ void axisdev88_init(MachineState *machine)
     /* allocate RAM */
     memory_region_allocate_system_memory(phys_ram, NULL, "axisdev88.ram",
                                          ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);
+    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram,
+                                &error_abort);
 
     /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the 
        internal memory.  */
     memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE,
                            &error_abort);
     vmstate_register_ram_global(phys_intmem);
-    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);
+    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem,
+                                &error_abort);
 
       /* Attach a NAND flash to CS1.  */
     nand = drive_get(IF_MTD, 0, 0);
@@ -288,13 +290,13 @@ void axisdev88_init(MachineState *machine)
     memory_region_init_io(&nand_state.iomem, NULL, &nand_ops, &nand_state,
                           "nand", 0x05000000);
     memory_region_add_subregion(address_space_mem, 0x10000000,
-                                &nand_state.iomem);
+                                &nand_state.iomem, &error_abort);
 
     gpio_state.nand = &nand_state;
     memory_region_init_io(&gpio_state.iomem, NULL, &gpio_ops, &gpio_state,
                           "gpio", 0x5c);
     memory_region_add_subregion(address_space_mem, 0x3001a000,
-                                &gpio_state.iomem);
+                                &gpio_state.iomem, &error_abort);
 
 
     dev = qdev_create(NULL, "etraxfs,pic");
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index 5198037..b2bd4a9 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -2892,7 +2892,8 @@ static void cirrus_init_common(CirrusVGAState *s, Object *owner,
     memory_region_init_io(&s->cirrus_vga_io, owner, &cirrus_vga_io_ops, s,
                           "cirrus-io", 0x30);
     memory_region_set_flush_coalesced(&s->cirrus_vga_io);
-    memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io);
+    memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io,
+                                &error_abort);
 
     memory_region_init(&s->low_mem_container, owner,
                        "cirrus-lowmem-container",
@@ -2900,7 +2901,8 @@ static void cirrus_init_common(CirrusVGAState *s, Object *owner,
 
     memory_region_init_io(&s->low_mem, owner, &cirrus_vga_mem_ops, s,
                           "cirrus-low-memory", 0x20000);
-    memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
+    memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem,
+                                &error_abort);
     for (i = 0; i < 2; ++i) {
         static const char *names[] = { "vga.bank0", "vga.bank1" };
         MemoryRegion *bank = &s->cirrus_bank[i];
@@ -3036,9 +3038,10 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
     memory_region_init(&s->pci_bar, OBJECT(dev), "cirrus-pci-bar0", 0x2000000);
 
     /* XXX: add byte swapping apertures */
-    memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
+    memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io,
+                                &error_abort);
     memory_region_add_subregion(&s->pci_bar, 0x1000000,
-                                &s->cirrus_linear_bitblt_io);
+                                &s->cirrus_linear_bitblt_io, &error_abort);
 
      /* setup memory space */
      /* memory #0 LFB */
diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c
index f1fef27..7cb255e 100644
--- a/hw/display/omap_dss.c
+++ b/hw/display/omap_dss.c
@@ -1073,7 +1073,7 @@ struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
     omap_l4_attach(ta, 1, &s->iomem_disc1);
     omap_l4_attach(ta, 2, &s->iomem_rfbi1);
     omap_l4_attach(ta, 3, &s->iomem_venc1);
-    memory_region_add_subregion(sysmem, l3_base, &s->iomem_im3);
+    memory_region_add_subregion(sysmem, l3_base, &s->iomem_im3, &error_abort);
 
 #if 0
     s->state = graphic_console_init(omap_update_display,
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
index fda81ba..63ec081 100644
--- a/hw/display/omap_lcdc.c
+++ b/hw/display/omap_lcdc.c
@@ -404,7 +404,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
     omap_lcdc_reset(s);
 
     memory_region_init_io(&s->iomem, NULL, &omap_lcdc_ops, s, "omap.lcdc", 0x100);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     s->con = graphic_console_init(NULL, 0, &omap_ops, s);
 
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
index ac3c018..7672aa5 100644
--- a/hw/display/pxa2xx_lcd.c
+++ b/hw/display/pxa2xx_lcd.c
@@ -1001,7 +1001,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
 
     memory_region_init_io(&s->iomem, NULL, &pxa2xx_lcdc_ops, s,
                           "pxa2xx-lcd-controller", 0x00100000);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
     surface = qemu_console_surface(s->con);
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 15a5ba8..b7a7fbd 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -1415,23 +1415,24 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
     vmstate_register_ram_global(&s->local_mem_region);
     memory_region_set_log(&s->local_mem_region, true, DIRTY_MEMORY_VGA);
     s->local_mem = memory_region_get_ram_ptr(&s->local_mem_region);
-    memory_region_add_subregion(address_space_mem, base, &s->local_mem_region);
+    memory_region_add_subregion(address_space_mem, base, &s->local_mem_region,
+                                &error_abort);
 
     /* map mmio */
     memory_region_init_io(sm501_system_config, NULL, &sm501_system_config_ops, s,
                           "sm501-system-config", 0x6c);
     memory_region_add_subregion(address_space_mem, base + MMIO_BASE_OFFSET,
-                                sm501_system_config);
+                                sm501_system_config, &error_abort);
     memory_region_init_io(sm501_disp_ctrl, NULL, &sm501_disp_ctrl_ops, s,
                           "sm501-disp-ctrl", 0x1000);
     memory_region_add_subregion(address_space_mem,
                                 base + MMIO_BASE_OFFSET + SM501_DC,
-                                sm501_disp_ctrl);
+                                sm501_disp_ctrl, &error_abort);
     memory_region_init_io(sm501_2d_engine, NULL, &sm501_2d_engine_ops, s,
                           "sm501-2d-engine", 0x54);
     memory_region_add_subregion(address_space_mem,
                                 base + MMIO_BASE_OFFSET + SM501_2D_ENGINE,
-                                sm501_2d_engine);
+                                sm501_2d_engine, &error_abort);
 
     /* bridge to usb host emulation module */
     dev = qdev_create(NULL, "sysbus-ohci");
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index f5f3f3e..a2f64ec 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -581,13 +581,14 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
                          NAND_MFR_TOSHIBA, 0x76);
 
     memory_region_init_io(&s->iomem, NULL, &tc6393xb_ops, s, "tc6393xb", 0x10000);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     memory_region_init_ram(&s->vram, NULL, "tc6393xb.vram", 0x100000,
                            &error_abort);
     vmstate_register_ram_global(&s->vram);
     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
-    memory_region_add_subregion(sysmem, base + 0x100000, &s->vram);
+    memory_region_add_subregion(sysmem, base + 0x100000, &s->vram,
+                                &error_abort);
     s->scr_width = 480;
     s->scr_height = 640;
     s->con = graphic_console_init(NULL, 0, &tc6393xb_gfx_ops, s);
diff --git a/hw/display/vga-isa-mm.c b/hw/display/vga-isa-mm.c
index 4efc222..1c58361 100644
--- a/hw/display/vga-isa-mm.c
+++ b/hw/display/vga-isa-mm.c
@@ -116,10 +116,12 @@ static void vga_mm_init(ISAVGAMMState *s, hwaddr vram_base,
 
     vmstate_register(NULL, 0, &vmstate_vga_common, s);
 
-    memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl);
+    memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl,
+                                &error_abort);
     s->vga.bank_offset = 0;
     memory_region_add_subregion(address_space,
-                                vram_base + 0x000a0000, vga_io_memory);
+                                vram_base + 0x000a0000, vga_io_memory,
+                                &error_abort);
     memory_region_set_coalescing(vga_io_memory);
 }
 
diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index 1dfa331..504ebb6 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -212,18 +212,18 @@ void pci_std_vga_mmio_region_init(VGACommonState *s,
     memory_region_init_io(&subs[0], NULL, &pci_vga_ioport_ops, s,
                           "vga ioports remapped", PCI_VGA_IOPORT_SIZE);
     memory_region_add_subregion(parent, PCI_VGA_IOPORT_OFFSET,
-                                &subs[0]);
+                                &subs[0], &error_abort);
 
     memory_region_init_io(&subs[1], NULL, &pci_vga_bochs_ops, s,
                           "bochs dispi interface", PCI_VGA_BOCHS_SIZE);
     memory_region_add_subregion(parent, PCI_VGA_BOCHS_OFFSET,
-                                &subs[1]);
+                                &subs[1], &error_abort);
 
     if (qext) {
         memory_region_init_io(&subs[2], NULL, &pci_vga_qext_ops, s,
                               "qemu extended regs", PCI_VGA_QEXT_SIZE);
         memory_region_add_subregion(parent, PCI_VGA_QEXT_OFFSET,
-                                    &subs[2]);
+                                    &subs[2], &error_abort);
     }
 }
 
diff --git a/hw/display/vga.c b/hw/display/vga.c
index b35d523..74bb4ed 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -2247,6 +2247,7 @@ void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
     /* XXX: use optimized standard vga accesses */
     memory_region_add_subregion(system_memory,
                                 VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                &s->vram_vbe);
+                                &s->vram_vbe,
+                                &error_abort);
     s->vbe_mapped = 1;
 }
diff --git a/hw/dma/etraxfs_dma.c b/hw/dma/etraxfs_dma.c
index 3599513..7fd23dc 100644
--- a/hw/dma/etraxfs_dma.c
+++ b/hw/dma/etraxfs_dma.c
@@ -775,7 +775,8 @@ void *etraxfs_dmac_init(hwaddr base, int nr_channels)
 
 	memory_region_init_io(&ctrl->mmio, NULL, &dma_ops, ctrl, "etraxfs-dma",
 			      nr_channels * 0x2000);
-	memory_region_add_subregion(get_system_memory(), base, &ctrl->mmio);
+        memory_region_add_subregion(get_system_memory(), base, &ctrl->mmio,
+                                    &error_abort);
 
 	return ctrl;
 }
diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
index a414029..15087ce 100644
--- a/hw/dma/i8257.c
+++ b/hw/dma/i8257.c
@@ -526,7 +526,7 @@ static void dma_init2(struct dma_cont *d, int base, int dshift,
     memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d,
                           "dma-chan", 8 << d->dshift);
     memory_region_add_subregion(isa_address_space_io(NULL),
-                                base, &d->channel_io);
+                                base, &d->channel_io, &error_abort);
 
     isa_register_portio_list(NULL, page_base, page_portio_list, d,
                              "dma-page");
@@ -538,7 +538,8 @@ static void dma_init2(struct dma_cont *d, int base, int dshift,
     memory_region_init_io(&d->cont_io, NULL, &cont_io_ops, d, "dma-cont",
                           8 << d->dshift);
     memory_region_add_subregion(isa_address_space_io(NULL),
-                                base + (8 << d->dshift), &d->cont_io);
+                                base + (8 << d->dshift), &d->cont_io,
+                                &error_abort);
 
     qemu_register_reset(dma_reset, d);
     dma_reset(d);
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
index 97c57a0..02e7a15 100644
--- a/hw/dma/omap_dma.c
+++ b/hw/dma/omap_dma.c
@@ -1666,7 +1666,7 @@ struct soc_dma_s *omap_dma_init(hwaddr base, qemu_irq *irqs,
     omap_dma_clk_update(s, 0, 1);
 
     memory_region_init_io(&s->iomem, NULL, &omap_dma_ops, s, "omap.dma", memsize);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     mpu->drq = s->dma->drq;
 
@@ -2089,7 +2089,7 @@ struct soc_dma_s *omap_dma4_init(hwaddr base, qemu_irq *irqs,
     omap_dma_clk_update(s, 0, !!s->dma->freq);
 
     memory_region_init_io(&s->iomem, NULL, &omap_dma4_ops, s, "omap.dma4", 0x1000);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     mpu->drq = s->dma->drq;
 
diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 3efa6de..2340b89 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -336,7 +336,7 @@ static void rc4030_dma_tt_update(rc4030State *s, uint32_t new_tl_base,
             rc4030_dma_as_update_one(s, i, dma_tl_contents[i].frame);
         }
         memory_region_add_subregion(get_system_memory(), new_tl_base,
-                                    &s->dma_tt_alias);
+                                    &s->dma_tt_alias, &error_abort);
         memory_region_transaction_commit();
     } else {
         memory_region_init(&s->dma_tt_alias, OBJECT(s),
@@ -782,7 +782,7 @@ static void rc4030_realize(DeviceState *dev, Error **errp)
                                  get_system_memory(), 0, DMA_PAGESIZE);
         memory_region_set_enabled(&s->dma_mrs[i], false);
         memory_region_add_subregion(&s->dma_mr, i * DMA_PAGESIZE,
-                                    &s->dma_mrs[i]);
+                                    &s->dma_mrs[i], &error_abort);
     }
     address_space_init(&s->dma_as, &s->dma_mr, "rc4030-dma");
 }
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 74d22f4..b177355 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -267,7 +267,8 @@ static void assigned_dev_iomem_setup(PCIDevice *pci_dev, int region_num,
     if (e_size > 0) {
         memory_region_init(&region->container, OBJECT(pci_dev),
                            "assigned-dev-container", e_size);
-        memory_region_add_subregion(&region->container, 0, &region->real_iomem);
+        memory_region_add_subregion(&region->container, 0, &region->real_iomem,
+                                    &error_abort);
 
         /* deal with MSI-X MMIO page */
         if (real_region->base_addr <= r_dev->msix_table_addr &&
@@ -301,7 +302,8 @@ static void assigned_dev_ioport_setup(PCIDevice *pci_dev, int region_num,
     memory_region_init_io(&region->real_iomem, OBJECT(pci_dev),
                           &assigned_dev_ioport_ops, r_dev->v_addrs + region_num,
                           "assigned-dev-iomem", size);
-    memory_region_add_subregion(&region->container, 0, &region->real_iomem);
+    memory_region_add_subregion(&region->container, 0, &region->real_iomem,
+                                &error_abort);
 }
 
 static uint32_t assigned_dev_pci_read(PCIDevice *d, int pos, int len)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index bd79d25..9afc653 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1256,14 +1256,14 @@ FWCfgState *pc_memory_init(MachineState *machine,
     ram_below_4g = g_malloc(sizeof(*ram_below_4g));
     memory_region_init_alias(ram_below_4g, NULL, "ram-below-4g", ram,
                              0, below_4g_mem_size);
-    memory_region_add_subregion(system_memory, 0, ram_below_4g);
+    memory_region_add_subregion(system_memory, 0, ram_below_4g, &error_abort);
     e820_add_entry(0, below_4g_mem_size, E820_RAM);
     if (above_4g_mem_size > 0) {
         ram_above_4g = g_malloc(sizeof(*ram_above_4g));
         memory_region_init_alias(ram_above_4g, NULL, "ram-above-4g", ram,
                                  below_4g_mem_size, above_4g_mem_size);
         memory_region_add_subregion(system_memory, 0x100000000ULL,
-                                    ram_above_4g);
+                                    ram_above_4g, &error_abort);
         e820_add_entry(0x100000000ULL, above_4g_mem_size, E820_RAM);
     }
 
@@ -1314,7 +1314,7 @@ FWCfgState *pc_memory_init(MachineState *machine,
         memory_region_init_hva_range(&pcms->hotplug_memory.mr, OBJECT(pcms),
                                      "hotplug-memory", hotplug_mem_size);
         memory_region_add_subregion(system_memory, pcms->hotplug_memory.base,
-                                    &pcms->hotplug_memory.mr);
+                                    &pcms->hotplug_memory.mr, &error_abort);
     }
 
     /* Initialize PC system firmware */
@@ -1418,10 +1418,12 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
     MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);
 
     memory_region_init_io(ioport80_io, NULL, &ioport80_io_ops, NULL, "ioport80", 1);
-    memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io);
+    memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io,
+                                &error_abort);
 
     memory_region_init_io(ioportF0_io, NULL, &ioportF0_io_ops, NULL, "ioportF0", 1);
-    memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io);
+    memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io,
+                                &error_abort);
 
     /*
      * Check if an HPET shall be created.
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 662d997..4b98777 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -225,7 +225,7 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
     /* map all the bios at the top of memory */
     memory_region_add_subregion(rom_memory,
                                 (uint32_t)(-bios_size),
-                                bios);
+                                bios, &error_abort);
 }
 
 void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 66fb9d9..ac78f69 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -251,11 +251,13 @@ static void bmdma_setup_bar(PCIIDEState *d)
         bm = &d->bmdma[i];
         memory_region_init_io(&bm->extra_io, OBJECT(d), &cmd646_bmdma_ops, bm,
                               "cmd646-bmdma-bus", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io,
+                                    &error_abort);
         memory_region_init_io(&bm->addr_ioport, OBJECT(d),
                               &bmdma_addr_ioport_ops, bm,
                               "cmd646-bmdma-ioport", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport,
+                                    &error_abort);
     }
 }
 
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index adb6649..70acfce 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -96,10 +96,12 @@ static void bmdma_setup_bar(PCIIDEState *d)
 
         memory_region_init_io(&bm->extra_io, OBJECT(d), &piix_bmdma_ops, bm,
                               "piix-bmdma", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io,
+                                    &error_abort);
         memory_region_init_io(&bm->addr_ioport, OBJECT(d),
                               &bmdma_addr_ioport_ops, bm, "bmdma", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport,
+                                    &error_abort);
     }
 }
 
diff --git a/hw/ide/via.c b/hw/ide/via.c
index e2da9ef..5efb906 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -98,10 +98,12 @@ static void bmdma_setup_bar(PCIIDEState *d)
 
         memory_region_init_io(&bm->extra_io, OBJECT(d), &via_bmdma_ops, bm,
                               "via-bmdma", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io,
+                                    &error_abort);
         memory_region_init_io(&bm->addr_ioport, OBJECT(d),
                               &bmdma_addr_ioport_ops, bm, "bmdma", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport,
+                                    &error_abort);
     }
 }
 
diff --git a/hw/input/pxa2xx_keypad.c b/hw/input/pxa2xx_keypad.c
index 8501114..e2bde81 100644
--- a/hw/input/pxa2xx_keypad.c
+++ b/hw/input/pxa2xx_keypad.c
@@ -314,7 +314,7 @@ PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
 
     memory_region_init_io(&s->iomem, NULL, &pxa2xx_keypad_ops, s,
                           "pxa2xx-keypad", 0x00100000);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     vmstate_register(NULL, 0, &vmstate_pxa2xx_keypad, s);
 
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 0032b97..e65b66d 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -309,7 +309,8 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
     info->realize(dev, errp);
     if (!mmio_registered) {
         ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev));
-        memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory);
+        memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory,
+                                    &error_abort);
         mmio_registered = true;
     }
 
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index e13b729..4b0f1c3 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -511,7 +511,7 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
      */
     memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
                           "nvic_sysregs", 0x1000);
-    memory_region_add_subregion(&s->container, 0, &s->sysregmem);
+    memory_region_add_subregion(&s->container, 0, &s->sysregmem, &error_abort);
     /* Alias the GIC region so we can get only the section of it
      * we need, and layer it on top of the system register region.
      */
@@ -523,7 +523,8 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
     /* Map the whole thing into system memory at the location required
      * by the v7M architecture.
      */
-    memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container);
+    memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container,
+                                &error_abort);
     s->systick.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, systick_timer_tick, s);
 }
 
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
index b2a4950..57b6d1f 100644
--- a/hw/intc/exynos4210_gic.c
+++ b/hw/intc/exynos4210_gic.c
@@ -318,7 +318,8 @@ static int exynos4210_gic_init(SysBusDevice *sbd)
                                  0,
                                  EXYNOS4210_GIC_CPU_REGION_SIZE);
         memory_region_add_subregion(&s->cpu_container,
-                EXYNOS4210_EXT_GIC_CPU_GET_OFFSET(i), &s->cpu_alias[i]);
+                EXYNOS4210_EXT_GIC_CPU_GET_OFFSET(i), &s->cpu_alias[i],
+                &error_abort);
 
         /* Map Distributor per SMP Core */
         sprintf(dist_alias_name, "%s%x", dist_prefix, i);
@@ -328,7 +329,8 @@ static int exynos4210_gic_init(SysBusDevice *sbd)
                                  0,
                                  EXYNOS4210_GIC_DIST_REGION_SIZE);
         memory_region_add_subregion(&s->dist_container,
-                EXYNOS4210_EXT_GIC_DIST_GET_OFFSET(i), &s->dist_alias[i]);
+                EXYNOS4210_EXT_GIC_DIST_GET_OFFSET(i), &s->dist_alias[i],
+                &error_abort);
     }
 
     sysbus_init_mmio(sbd, &s->cpu_container);
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
index 14ab0e3..b9aa8e6 100644
--- a/hw/intc/openpic.c
+++ b/hw/intc/openpic.c
@@ -1401,7 +1401,7 @@ static void map_list(OpenPICState *opp, const MemReg *list, int *count)
                               opp, list->name, list->size);
 
         memory_region_add_subregion(&opp->mem, list->start_addr,
-                                    &opp->sub_io_mem[*count]);
+                                    &opp->sub_io_mem[*count], &error_abort);
 
         (*count)++;
         list++;
diff --git a/hw/intc/realview_gic.c b/hw/intc/realview_gic.c
index 6c81296..da7dff7 100644
--- a/hw/intc/realview_gic.c
+++ b/hw/intc/realview_gic.c
@@ -43,9 +43,11 @@ static void realview_gic_realize(DeviceState *dev, Error **errp)
     qdev_init_gpio_in(dev, realview_gic_set_irq, numirq - 32);
 
     memory_region_add_subregion(&s->container, 0,
-                                sysbus_mmio_get_region(busdev, 1));
+                                sysbus_mmio_get_region(busdev, 1),
+                                &error_abort);
     memory_region_add_subregion(&s->container, 0x1000,
-                                sysbus_mmio_get_region(busdev, 0));
+                                sysbus_mmio_get_region(busdev, 0),
+                                &error_abort);
 }
 
 static void realview_gic_init(Object *obj)
diff --git a/hw/intc/sh_intc.c b/hw/intc/sh_intc.c
index 55c76e4..56c903f 100644
--- a/hw/intc/sh_intc.c
+++ b/hw/intc/sh_intc.c
@@ -319,11 +319,13 @@ static unsigned int sh_intc_register(MemoryRegion *sysmem,
 #define SH_INTC_IOMEM_FORMAT "interrupt-controller-%s-%s-%s"
     snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "p4");
     memory_region_init_alias(iomem_p4, NULL, name, iomem, INTC_A7(address), 4);
-    memory_region_add_subregion(sysmem, P4ADDR(address), iomem_p4);
+    memory_region_add_subregion(sysmem, P4ADDR(address), iomem_p4,
+                                &error_abort);
 
     snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "a7");
     memory_region_init_alias(iomem_a7, NULL, name, iomem, INTC_A7(address), 4);
-    memory_region_add_subregion(sysmem, A7ADDR(address), iomem_a7);
+    memory_region_add_subregion(sysmem, A7ADDR(address), iomem_a7,
+                                &error_abort);
 #undef SH_INTC_IOMEM_FORMAT
 
     /* used to increment aliases index */
diff --git a/hw/isa/apm.c b/hw/isa/apm.c
index 26ab170..f1709db 100644
--- a/hw/isa/apm.c
+++ b/hw/isa/apm.c
@@ -98,5 +98,5 @@ void apm_init(PCIDevice *dev, APMState *apm, apm_ctrl_changed_t callback,
     /* ioport 0xb2, 0xb3 */
     memory_region_init_io(&apm->io, OBJECT(dev), &apm_ops, apm, "apm-io", 2);
     memory_region_add_subregion(pci_address_space_io(dev), APM_CNT_IOPORT,
-                                &apm->io);
+                                &apm->io, &error_abort);
 }
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 43e0cd8..b1d311a 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -101,7 +101,8 @@ static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
 
 void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
 {
-    memory_region_add_subregion(isabus->address_space_io, start, io);
+    memory_region_add_subregion(isabus->address_space_io, start, io,
+                                &error_abort);
     isa_init_ioport(dev, start);
 }
 
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 252e1d7..3db63ea 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -362,13 +362,14 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp)
     pci_conf[0x91] = s->smb_io_base >> 8;
     pci_conf[0xd2] = 0x90;
     pm_smbus_init(&s->dev.qdev, &s->smb);
-    memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
+    memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io,
+                                &error_abort);
 
     apm_init(dev, &s->apm, NULL, s);
 
     memory_region_init(&s->io, OBJECT(dev), "vt82c686-pm", 64);
     memory_region_set_enabled(&s->io, false);
-    memory_region_add_subregion(get_system_io(), 0, &s->io);
+    memory_region_add_subregion(get_system_io(), 0, &s->io, &error_abort);
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
@@ -458,7 +459,7 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp)
     /* The floppy also uses 0x3f0 and 0x3f1.
      * But we do not emulate a floppy, so just set it here. */
     memory_region_add_subregion(isa_bus->address_space_io, 0x3f0,
-                                &vt82c->superio);
+                                &vt82c->superio, &error_abort);
 
     qemu_register_reset(vt82c686b_reset, d);
 }
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 70f48d3..ff744fd 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -113,7 +113,8 @@ static void lm32_evr_init(MachineState *machine)
 
     memory_region_allocate_system_memory(phys_ram, NULL, "lm32_evr.sdram",
                                          ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    memory_region_add_subregion(address_space_mem, ram_base, phys_ram,
+                                &error_abort);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
@@ -214,7 +215,8 @@ static void lm32_uclinux_init(MachineState *machine)
 
     memory_region_allocate_system_memory(phys_ram, NULL,
                                          "lm32_uclinux.sdram", ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    memory_region_add_subregion(address_space_mem, ram_base, phys_ram,
+                                &error_abort);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index e755f5b..0f35218 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -120,7 +120,8 @@ milkymist_init(MachineState *machine)
 
     memory_region_allocate_system_memory(phys_sdram, NULL, "milkymist.sdram",
                                          sdram_size);
-    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);
+    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram,
+                                &error_abort);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Numonyx JS28F256J3F105 */
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index f63ab2b..cba086e 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -51,12 +51,13 @@ static void an5206_init(MachineState *machine)
 
     /* DRAM at address zero */
     memory_region_allocate_system_memory(ram, NULL, "an5206.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
 
     /* Internal SRAM.  */
     memory_region_init_ram(sram, NULL, "an5206.sram", 512, &error_abort);
     vmstate_register_ram_global(sram);
-    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
+    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram,
+                                &error_abort);
 
     mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, cpu);
 
diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
index 5b77d93..5561adf 100644
--- a/hw/m68k/dummy_m68k.c
+++ b/hw/m68k/dummy_m68k.c
@@ -44,7 +44,7 @@ static void dummy_m68k_init(MachineState *machine)
     /* RAM at address zero */
     memory_region_allocate_system_memory(ram, NULL, "dummy_m68k.ram",
                                          ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
 
     /* Load kernel.  */
     if (kernel_filename) {
diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c
index 1727a46..b0e15c6 100644
--- a/hw/m68k/mcf5206.c
+++ b/hw/m68k/mcf5206.c
@@ -534,7 +534,7 @@ qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, M68kCPU *cpu)
 
     memory_region_init_io(&s->iomem, NULL, &m5206_mbar_ops, s,
                           "mbar", 0x00001000);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     pic = qemu_allocate_irqs(m5206_mbar_set_irq, s, 14);
     s->timer[0] = m5206_timer_init(pic[9]);
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 326a42d..e080ed6 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -174,7 +174,7 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
 
     /* SDRAMC.  */
     memory_region_init_io(iomem, NULL, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
-    memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
+    memory_region_add_subregion(address_space, 0xfc0a8000, iomem, &error_abort);
     /* Timers.  */
     for (i = 0; i < 2; i++) {
         s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
@@ -183,7 +183,7 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
         memory_region_init_io(&s->iomem, NULL, &m5208_timer_ops, s,
                               "m5208-timer", 0x00004000);
         memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
-                                    &s->iomem);
+                                    &s->iomem, &error_abort);
         s->irq = pic[4 + i];
     }
 }
@@ -219,12 +219,14 @@ static void mcf5208evb_init(MachineState *machine)
 
     /* DRAM at 0x40000000 */
     memory_region_allocate_system_memory(ram, NULL, "mcf5208.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
+    memory_region_add_subregion(address_space_mem, 0x40000000, ram,
+                                &error_abort);
 
     /* Internal SRAM.  */
     memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384, &error_abort);
     vmstate_register_ram_global(sram);
-    memory_region_add_subregion(address_space_mem, 0x80000000, sram);
+    memory_region_add_subregion(address_space_mem, 0x80000000, sram,
+                                &error_abort);
 
     /* Internal peripherals.  */
     pic = mcf_intc_init(address_space_mem, 0xfc048000, cpu);
diff --git a/hw/m68k/mcf_intc.c b/hw/m68k/mcf_intc.c
index f13c7f3..3c6c5e5 100644
--- a/hw/m68k/mcf_intc.c
+++ b/hw/m68k/mcf_intc.c
@@ -162,7 +162,7 @@ qemu_irq *mcf_intc_init(MemoryRegion *sysmem,
     mcf_intc_reset(s);
 
     memory_region_init_io(&s->iomem, NULL, &mcf_intc_ops, s, "mcf", 0x100);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     return qemu_allocate_irqs(mcf_intc_set_irq, s, 64);
 }
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index bb04862..8cc9118 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -95,7 +95,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
         goto out;
     }
 
-    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
+    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr, &error_abort);
     vmstate_register_ram(mr, dev);
     numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
 
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index ed84a37..19de681 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -94,12 +94,14 @@ petalogix_ml605_init(MachineState *machine)
     memory_region_init_ram(phys_lmb_bram, NULL, "petalogix_ml605.lmb_bram",
                            LMB_BRAM_SIZE, &error_abort);
     vmstate_register_ram_global(phys_lmb_bram);
-    memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram);
+    memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram,
+                                &error_abort);
 
     memory_region_init_ram(phys_ram, NULL, "petalogix_ml605.ram", ram_size,
                            &error_abort);
     vmstate_register_ram_global(phys_ram);
-    memory_region_add_subregion(address_space_mem, MEMORY_BASEADDR, phys_ram);
+    memory_region_add_subregion(address_space_mem, MEMORY_BASEADDR, phys_ram,
+                                &error_abort);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* 5th parameter 2 means bank-width
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index 0c2140c..62e6563 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -73,12 +73,13 @@ petalogix_s3adsp1800_init(MachineState *machine)
                            "petalogix_s3adsp1800.lmb_bram", LMB_BRAM_SIZE,
                            &error_abort);
     vmstate_register_ram_global(phys_lmb_bram);
-    memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);
+    memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram,
+                                &error_abort);
 
     memory_region_init_ram(phys_ram, NULL, "petalogix_s3adsp1800.ram",
                            ram_size, &error_abort);
     vmstate_register_ram_global(phys_ram);
-    memory_region_add_subregion(sysmem, ddr_base, phys_ram);
+    memory_region_add_subregion(sysmem, ddr_base, phys_ram, &error_abort);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(FLASH_BASEADDR,
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 10fcca3..7c630bc 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -289,7 +289,8 @@ static void gt64120_isd_mapping(GT64120State *s)
         s->ISD_length, s->ISD_start, length, start);
     s->ISD_start = start;
     s->ISD_length = length;
-    memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem);
+    memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem,
+                                &error_abort);
 }
 
 static void gt64120_pci_mapping(GT64120State *s)
@@ -309,7 +310,7 @@ static void gt64120_pci_mapping(GT64120State *s)
             memory_region_init_alias(&s->PCI0IO_mem, OBJECT(s), "pci0-io",
                                      get_system_io(), 0, s->PCI0IO_length);
             memory_region_add_subregion(get_system_memory(), s->PCI0IO_start,
-                                        &s->PCI0IO_mem);
+                                        &s->PCI0IO_mem, &error_abort);
         }
     }
 
@@ -329,7 +330,7 @@ static void gt64120_pci_mapping(GT64120State *s)
                                      &s->pci0_mem, s->PCI0M0_start,
                                      s->PCI0M0_length);
             memory_region_add_subregion(get_system_memory(), s->PCI0M0_start,
-                                        &s->PCI0M0_mem);
+                                        &s->PCI0M0_mem, &error_abort);
         }
     }
 
@@ -349,7 +350,7 @@ static void gt64120_pci_mapping(GT64120State *s)
                                      &s->pci0_mem, s->PCI0M1_start,
                                      s->PCI0M1_length);
             memory_region_add_subregion(get_system_memory(), s->PCI0M1_start,
-                                        &s->PCI0M1_mem);
+                                        &s->PCI0M1_mem, &error_abort);
         }
     }
 }
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index dea941a..1ed8d1b 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -308,8 +308,9 @@ static void mips_fulong2e_init(MachineState *machine)
     vmstate_register_ram_global(bios);
     memory_region_set_readonly(bios, true);
 
-    memory_region_add_subregion(address_space_mem, 0, ram);
-    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios);
+    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
+    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios,
+                                &error_abort);
 
     /* We do not support flash operation, just loading pmon.bin as raw BIOS.
      * Please use -L to set the BIOS path and -bios to set bios name. */
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 9d60633..1c49704 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -181,7 +181,7 @@ static void mips_jazz_init(MachineState *machine,
     /* allocate RAM */
     memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
                                          machine->ram_size);
-    memory_region_add_subregion(address_space, 0, ram);
+    memory_region_add_subregion(address_space, 0, ram, &error_abort);
 
     memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE,
                            &error_abort);
@@ -189,8 +189,10 @@ static void mips_jazz_init(MachineState *machine,
     memory_region_set_readonly(bios, true);
     memory_region_init_alias(bios2, NULL, "mips_jazz.bios", bios,
                              0, MAGNUM_BIOS_SIZE);
-    memory_region_add_subregion(address_space, 0x1fc00000LL, bios);
-    memory_region_add_subregion(address_space, 0xfff00000LL, bios2);
+    memory_region_add_subregion(address_space, 0x1fc00000LL, bios,
+                                &error_abort);
+    memory_region_add_subregion(address_space, 0xfff00000LL, bios2,
+                                &error_abort);
 
     /* load the BIOS image. */
     if (bios_name == NULL)
@@ -218,17 +220,22 @@ static void mips_jazz_init(MachineState *machine,
     sysbus_connect_irq(sysbus, 0, env->irq[6]);
     sysbus_connect_irq(sysbus, 1, env->irq[3]);
     memory_region_add_subregion(address_space, 0x80000000,
-                                sysbus_mmio_get_region(sysbus, 0));
+                                sysbus_mmio_get_region(sysbus, 0),
+                                &error_abort);
     memory_region_add_subregion(address_space, 0xf0000000,
-                                sysbus_mmio_get_region(sysbus, 1));
+                                sysbus_mmio_get_region(sysbus, 1),
+                                &error_abort);
     memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000);
-    memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
+    memory_region_add_subregion(address_space, 0x8000d000, dma_dummy,
+                                &error_abort);
 
     /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */
     memory_region_init(isa_io, NULL, "isa-io", 0x00010000);
     memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
-    memory_region_add_subregion(address_space, 0x90000000, isa_io);
-    memory_region_add_subregion(address_space, 0x91000000, isa_mem);
+    memory_region_add_subregion(address_space, 0x90000000, isa_io,
+                                &error_abort);
+    memory_region_add_subregion(address_space, 0x91000000, isa_mem,
+                                &error_abort);
     isa_bus = isa_bus_new(NULL, isa_mem, isa_io);
 
     /* ISA devices */
@@ -256,7 +263,8 @@ static void mips_jazz_init(MachineState *machine,
             vmstate_register_ram_global(rom_mr);
             memory_region_set_readonly(rom_mr, true);
             uint8_t *rom = memory_region_get_ram_ptr(rom_mr);
-            memory_region_add_subregion(address_space, 0x60000000, rom_mr);
+            memory_region_add_subregion(address_space, 0x60000000, rom_mr,
+                                        &error_abort);
             rom[0] = 0x10; /* Mips G364 */
         }
         break;
@@ -312,12 +320,12 @@ static void mips_jazz_init(MachineState *machine,
     /* Real time clock */
     rtc_init(isa_bus, 1980, NULL);
     memory_region_init_io(rtc, NULL, &rtc_ops, NULL, "rtc", 0x1000);
-    memory_region_add_subregion(address_space, 0x80004000, rtc);
+    memory_region_add_subregion(address_space, 0x80004000, rtc, &error_abort);
 
     /* Keyboard (i8042) */
     i8042_mm_init(qdev_get_gpio_in(rc4030, 6), qdev_get_gpio_in(rc4030, 7),
                   i8042, 0x1000, 0x1);
-    memory_region_add_subregion(address_space, 0x80005000, i8042);
+    memory_region_add_subregion(address_space, 0x80005000, i8042, &error_abort);
 
     /* Serial ports */
     if (serial_hds[0]) {
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 3082e75..91863e6 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -552,8 +552,10 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
     memory_region_init_alias(&s->iomem_hi, NULL, "malta-fpga",
                              &s->iomem, 0xa00, 0x10000-0xa00);
 
-    memory_region_add_subregion(address_space, base, &s->iomem_lo);
-    memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
+    memory_region_add_subregion(address_space, base, &s->iomem_lo,
+                                &error_abort);
+    memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi,
+                                &error_abort);
 
     s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
 
@@ -1005,12 +1007,13 @@ void mips_malta_init(MachineState *machine)
     /* register RAM at high address where it is undisturbed by IO */
     memory_region_allocate_system_memory(ram_high, NULL, "mips_malta.ram",
                                          ram_size);
-    memory_region_add_subregion(system_memory, 0x80000000, ram_high);
+    memory_region_add_subregion(system_memory, 0x80000000, ram_high,
+                                &error_abort);
 
     /* alias for pre IO hole access */
     memory_region_init_alias(ram_low_preio, NULL, "mips_malta_low_preio.ram",
                              ram_high, 0, MIN(ram_size, (256 << 20)));
-    memory_region_add_subregion(system_memory, 0, ram_low_preio);
+    memory_region_add_subregion(system_memory, 0, ram_low_preio, &error_abort);
 
     /* alias for post IO hole access, if there is enough RAM */
     if (ram_size > (512 << 20)) {
@@ -1019,7 +1022,8 @@ void mips_malta_init(MachineState *machine)
                                  "mips_malta_low_postio.ram",
                                  ram_high, 512 << 20,
                                  ram_size - (512 << 20));
-        memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio);
+        memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio,
+                                    &error_abort);
     }
 
     /* generate SPD EEPROM data */
@@ -1137,7 +1141,8 @@ void mips_malta_init(MachineState *machine)
                memory_region_get_ram_ptr(bios), BIOS_SIZE);
     }
     memory_region_set_readonly(bios_copy, true);
-    memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy);
+    memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy,
+                                &error_abort);
 
     /* Board ID = 0x420 (Malta Board with CoreLV) */
     stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 61f74a6..d11944f 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -129,7 +129,8 @@ static void mipsnet_init(int base, qemu_irq irq, NICInfo *nd)
     sysbus_connect_irq(s, 0, irq);
     memory_region_add_subregion(get_system_io(),
                                 base,
-                                sysbus_mmio_get_region(s, 0));
+                                sysbus_mmio_get_region(s, 0),
+                                &error_abort);
 }
 
 static void
@@ -178,10 +179,11 @@ mips_mipssim_init(MachineState *machine)
     vmstate_register_ram_global(bios);
     memory_region_set_readonly(bios, true);
 
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
 
     /* Map the BIOS / boot exception handler. */
-    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios);
+    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios,
+                                &error_abort);
     /* Load a BIOS / boot exception handler image. */
     if (bios_name == NULL)
         bios_name = BIOS_FILENAME;
@@ -218,7 +220,8 @@ mips_mipssim_init(MachineState *machine)
     /* Register 64 KB of ISA IO space at 0x1fd00000. */
     memory_region_init_alias(isa, NULL, "isa_mmio",
                              get_system_io(), 0, 0x00010000);
-    memory_region_add_subregion(get_system_memory(), 0x1fd00000, isa);
+    memory_region_add_subregion(get_system_memory(), 0x1fd00000, isa,
+                                &error_abort);
 
     /* A single 16450 sits at offset 0x3f8. It is attached to
        MIPS CPU INT2, which is interrupt 4. */
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index f4dcacd..cd52d83 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -208,10 +208,11 @@ void mips_r4k_init(MachineState *machine)
     }
     memory_region_allocate_system_memory(ram, NULL, "mips_r4k.ram", ram_size);
 
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
 
     memory_region_init_io(iomem, NULL, &mips_qemu_ops, NULL, "mips-qemu", 0x10000);
-    memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem);
+    memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem,
+                                &error_abort);
 
     /* Try to load a BIOS image. If this fails, we continue regardless,
        but initialize the hardware ourselves. When a kernel gets
@@ -236,7 +237,8 @@ void mips_r4k_init(MachineState *machine)
                                &error_abort);
         vmstate_register_ram_global(bios);
         memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios);
+        memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios,
+                                    &error_abort);
 
         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
@@ -272,8 +274,10 @@ void mips_r4k_init(MachineState *machine)
     memory_region_init_alias(isa_io, NULL, "isa-io",
                              get_system_io(), 0, 0x00010000);
     memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
-    memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io);
-    memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem);
+    memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io,
+                                &error_abort);
+    memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem,
+                                &error_abort);
     isa_bus = isa_bus_new(NULL, isa_mem, get_system_io());
 
     /* The PIC is attached to the MIPS CPU INT0 pin */
diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c
index 69a1b00..df7142c 100644
--- a/hw/misc/debugexit.c
+++ b/hw/misc/debugexit.c
@@ -43,7 +43,7 @@ static void debug_exit_realizefn(DeviceState *d, Error **errp)
     memory_region_init_io(&isa->io, OBJECT(dev), &debug_exit_ops, isa,
                           TYPE_ISA_DEBUG_EXIT_DEVICE, isa->iosize);
     memory_region_add_subregion(isa_address_space_io(dev),
-                                isa->iobase, &isa->io);
+                                isa->iobase, &isa->io, &error_abort);
 }
 
 static Property debug_exit_properties[] = {
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index cc76989..65178e6 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -356,7 +356,7 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
     memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2",
                                s->ivshmem_size, ptr);
     vmstate_register_ram(&s->ivshmem, DEVICE(s));
-    memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
+    memory_region_add_subregion(&s->bar, 0, &s->ivshmem, &error_abort);
 
     /* region for shared memory */
     pci_register_bar(PCI_DEVICE(s), 2, s->ivshmem_attr, &s->bar);
@@ -535,7 +535,7 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size)
         IVSHMEM_DPRINTF("guest h/w addr = %p, size = %" PRIu64 "\n",
                         map_ptr, s->ivshmem_size);
 
-        memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
+        memory_region_add_subregion(&s->bar, 0, &s->ivshmem, &error_abort);
 
         /* only store the fd if it is successfully mapped */
         s->shm_fd = incoming_fd;
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index e9037b0..21229ed 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -110,10 +110,10 @@ static void macio_escc_legacy_setup(MacIOState *macio_state)
         MemoryRegion *port = g_new(MemoryRegion, 1);
         memory_region_init_alias(port, NULL, "escc-legacy-port",
                                  macio_state->escc_mem, maps[i+1], 0x2);
-        memory_region_add_subregion(escc_legacy, maps[i], port);
+        memory_region_add_subregion(escc_legacy, maps[i], port, &error_abort);
     }
 
-    memory_region_add_subregion(bar, 0x12000, escc_legacy);
+    memory_region_add_subregion(bar, 0x12000, escc_legacy, &error_abort);
 }
 
 static void macio_bar_setup(MacIOState *macio_state)
@@ -121,7 +121,8 @@ static void macio_bar_setup(MacIOState *macio_state)
     MemoryRegion *bar = &macio_state->bar;
 
     if (macio_state->escc_mem) {
-        memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
+        memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem,
+                                    &error_abort);
         macio_escc_legacy_setup(macio_state);
     }
 }
@@ -141,7 +142,8 @@ static void macio_common_realize(PCIDevice *d, Error **errp)
     }
     sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
     memory_region_add_subregion(&s->bar, 0x16000,
-                                sysbus_mmio_get_region(sysbus_dev, 0));
+                                sysbus_mmio_get_region(sysbus_dev, 0),
+                                &error_abort);
 
     macio_bar_setup(s);
     pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
@@ -185,12 +187,14 @@ static void macio_oldworld_realize(PCIDevice *d, Error **errp)
     }
     sysbus_dev = SYS_BUS_DEVICE(&os->nvram);
     memory_region_add_subregion(&s->bar, 0x60000,
-                                sysbus_mmio_get_region(sysbus_dev, 0));
+                                sysbus_mmio_get_region(sysbus_dev, 0),
+                                &error_abort);
     pmac_format_nvram_partition(&os->nvram, os->nvram.size);
 
     if (s->pic_mem) {
         /* Heathrow PIC */
-        memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem);
+        memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem,
+                                    &error_abort);
     }
 
     /* IDE buses */
@@ -214,7 +218,7 @@ static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, size_t ide_size,
     object_initialize(ide, ide_size, TYPE_MACIO_IDE);
     qdev_set_parent_bus(DEVICE(ide), sysbus_get_default());
     memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000),
-                                &ide->mem);
+                                &ide->mem, &error_abort);
     name = g_strdup_printf("ide[%i]", index);
     object_property_add_child(OBJECT(s), name, OBJECT(ide), NULL);
     g_free(name);
@@ -292,7 +296,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp)
 
     if (s->pic_mem) {
         /* OpenPIC */
-        memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
+        memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem, &error_abort);
     }
 
     /* IDE buses */
@@ -311,7 +315,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp)
     timer_memory = g_new(MemoryRegion, 1);
     memory_region_init_io(timer_memory, OBJECT(s), &timer_ops, NULL, "timer",
                           0x1000);
-    memory_region_add_subregion(&s->bar, 0x15000, timer_memory);
+    memory_region_add_subregion(&s->bar, 0x15000, timer_memory, &error_abort);
 }
 
 static void macio_newworld_init(Object *obj)
@@ -339,7 +343,7 @@ static void macio_instance_init(Object *obj)
     object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL);
 
     s->dbdma = DBDMA_init(&dbdma_mem);
-    memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
+    memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem, &error_abort);
 }
 
 static const VMStateDescription vmstate_macio_oldworld = {
diff --git a/hw/misc/omap_gpmc.c b/hw/misc/omap_gpmc.c
index 74fc91c..dcf6a96 100644
--- a/hw/misc/omap_gpmc.c
+++ b/hw/misc/omap_gpmc.c
@@ -419,9 +419,9 @@ static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
      * starting from <i>base</i>.  */
     memory_region_init(&f->container, NULL, "omap-gpmc-file", size);
     memory_region_add_subregion(&f->container, 0,
-                                omap_gpmc_cs_memregion(s, cs));
+                                omap_gpmc_cs_memregion(s, cs), &error_abort);
     memory_region_add_subregion(get_system_memory(), base,
-                                &f->container);
+                                &f->container, &error_abort);
 }
 
 static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
@@ -830,7 +830,8 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
             g_malloc0(sizeof(struct omap_gpmc_s));
 
     memory_region_init_io(&s->iomem, NULL, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
-    memory_region_add_subregion(get_system_memory(), base, &s->iomem);
+    memory_region_add_subregion(get_system_memory(), base, &s->iomem,
+                                &error_abort);
 
     s->irq = irq;
     s->drq = drq;
diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c
index 245ceac..3f7b333 100644
--- a/hw/misc/omap_l4.c
+++ b/hw/misc/omap_l4.c
@@ -156,7 +156,8 @@ hwaddr omap_l4_attach(struct omap_target_agent_s *ta,
 
     base = ta->bus->base + ta->start[region].offset;
     if (mr) {
-        memory_region_add_subregion(ta->bus->address_space, base, mr);
+        memory_region_add_subregion(ta->bus->address_space, base, mr,
+                                    &error_abort);
     }
 
     return base;
diff --git a/hw/misc/omap_sdrc.c b/hw/misc/omap_sdrc.c
index 3de0c0e..97dfab6 100644
--- a/hw/misc/omap_sdrc.c
+++ b/hw/misc/omap_sdrc.c
@@ -163,7 +163,7 @@ struct omap_sdrc_s *omap_sdrc_init(MemoryRegion *sysmem,
     omap_sdrc_reset(s);
 
     memory_region_init_io(&s->iomem, NULL, &omap_sdrc_ops, s, "omap.sdrc", 0x1000);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     return s;
 }
diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c
index 18e94e0..0c80244 100644
--- a/hw/misc/pc-testdev.c
+++ b/hw/misc/pc-testdev.c
@@ -177,11 +177,12 @@ static void testdev_realizefn(DeviceState *d, Error **errp)
     memory_region_init_io(&dev->iomem, OBJECT(dev), &test_iomem_ops, dev,
                           "pc-testdev-iomem", IOMEM_LEN);
 
-    memory_region_add_subregion(io,  0xe0,       &dev->ioport);
-    memory_region_add_subregion(io,  0xe4,       &dev->flush);
-    memory_region_add_subregion(io,  0xe8,       &dev->ioport_byte);
-    memory_region_add_subregion(io,  0x2000,     &dev->irq);
-    memory_region_add_subregion(mem, 0xff000000, &dev->iomem);
+    memory_region_add_subregion(io,  0xe0,       &dev->ioport, &error_abort);
+    memory_region_add_subregion(io,  0xe4,       &dev->flush, &error_abort);
+    memory_region_add_subregion(io,  0xe8,       &dev->ioport_byte,
+                                &error_abort);
+    memory_region_add_subregion(io,  0x2000,     &dev->irq, &error_abort);
+    memory_region_add_subregion(mem, 0xff000000, &dev->iomem, &error_abort);
 }
 
 static void testdev_class_init(ObjectClass *klass, void *data)
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index 80bcc5b..ca36d7d 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -125,11 +125,11 @@ static void moxiesim_init(MachineState *machine)
     /* Allocate RAM. */
     memory_region_init_ram(ram, NULL, "moxiesim.ram", ram_size, &error_abort);
     vmstate_register_ram_global(ram);
-    memory_region_add_subregion(address_space_mem, ram_base, ram);
+    memory_region_add_subregion(address_space_mem, ram_base, ram, &error_abort);
 
     memory_region_init_ram(rom, NULL, "moxie.rom", 128*0x1000, &error_abort);
     vmstate_register_ram_global(rom);
-    memory_region_add_subregion(get_system_memory(), 0x1000, rom);
+    memory_region_add_subregion(get_system_memory(), 0x1000, rom, &error_abort);
 
     if (kernel_filename) {
         loader_params.ram_size = ram_size;
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index c57365f..477ad01 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -450,7 +450,8 @@ DeviceState *etsec_create(hwaddr         base,
     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, err_irq);
 
     memory_region_add_subregion(mr, base,
-                                SYS_BUS_DEVICE(dev)->mmio[0].memory);
+                                SYS_BUS_DEVICE(dev)->mmio[0].memory,
+                                &error_abort);
 
     return dev;
 }
diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
index 0255612..a15f004 100644
--- a/hw/net/mcf_fec.c
+++ b/hw/net/mcf_fec.c
@@ -458,7 +458,7 @@ void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd,
     s->irq = irq;
 
     memory_region_init_io(&s->iomem, NULL, &mcf_fec_ops, s, "fec", 0x400);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     s->conf.macaddr = nd->macaddr;
     s->conf.peers.ncs[0] = nd->netdev;
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 1da0657..8d1a5fb 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -53,9 +53,9 @@ static void openrisc_sim_net_init(MemoryRegion *address_space,
     s = SYS_BUS_DEVICE(dev);
     sysbus_connect_irq(s, 0, irq);
     memory_region_add_subregion(address_space, base,
-                                sysbus_mmio_get_region(s, 0));
+                                sysbus_mmio_get_region(s, 0), &error_abort);
     memory_region_add_subregion(address_space, descriptors,
-                                sysbus_mmio_get_region(s, 1));
+                                sysbus_mmio_get_region(s, 1), &error_abort);
 }
 
 static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
@@ -116,7 +116,7 @@ static void openrisc_sim_init(MachineState *machine)
     ram = g_malloc(sizeof(*ram));
     memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, &error_abort);
     vmstate_register_ram_global(ram);
-    memory_region_add_subregion(get_system_memory(), 0, ram);
+    memory_region_add_subregion(get_system_memory(), 0, ram, &error_abort);
 
     cpu_openrisc_pic_init(cpu);
     cpu_openrisc_clock_init(cpu);
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 599768e..c472cc6 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -684,7 +684,8 @@ PCIBus *pci_apb_init(hwaddr special_base,
     d = APB_DEVICE(dev);
 
     memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
-    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
+    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio,
+                                &error_abort);
 
     phb = PCI_HOST_BRIDGE(dev);
     phb->bus = pci_register_bus(DEVICE(phb), "pci",
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index bfe707a..e1ff06b 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -80,7 +80,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
     memory_region_init_alias(&d->pci_hole, OBJECT(s), "pci-hole", &d->pci_mmio,
                              0x80000000ULL, 0x7e000000ULL);
     memory_region_add_subregion(address_space_mem, 0x80000000ULL,
-                                &d->pci_hole);
+                                &d->pci_hole, &error_abort);
 
     phb->bus = pci_register_bus(dev, NULL,
                                 pci_grackle_set_irq,
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index ad55f99..899ca92 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -355,7 +355,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low",
                              f->ram_memory, 0xa0000, 0x20000);
     memory_region_set_enabled(&f->low_smram, true);
-    memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
+    memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram,
+                                &error_abort);
     object_property_add_const_link(qdev_get_machine(), "smram",
                                    OBJECT(&f->smram), &error_abort);
 
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 613ba73..3de30c8 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -251,7 +251,7 @@ static void e500_update_pow(PPCE500PCIState *pci, int idx)
     name = g_strdup_printf("PCI Outbound Window %d", idx);
     memory_region_init_alias(mem, OBJECT(pci), name, &pci->busmem, tar,
                              size);
-    memory_region_add_subregion(address_space_mem, wbar, mem);
+    memory_region_add_subregion(address_space_mem, wbar, mem, &error_abort);
     g_free(name);
 
     pci_debug("%s: Added window of size=%#lx from CPU=%#lx to PCI=%#lx\n",
@@ -471,7 +471,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
 
     /* Set up PCI view of memory */
     memory_region_init(&s->bm, OBJECT(s), "bm-e500", UINT64_MAX);
-    memory_region_add_subregion(&s->bm, 0x0, &s->busmem);
+    memory_region_add_subregion(&s->bm, 0x0, &s->busmem, &error_abort);
     address_space_init(&s->bm_as, &s->bm, "pci-bm");
     pci_setup_iommu(b, e500_pcihost_set_iommu, s);
 
@@ -484,9 +484,12 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
                           "pci-conf-data", 4);
     memory_region_init_io(&s->iomem, OBJECT(s), &e500_pci_reg_ops, s,
                           "pci.reg", PCIE500_REG_SIZE);
-    memory_region_add_subregion(&s->container, PCIE500_CFGADDR, &h->conf_mem);
-    memory_region_add_subregion(&s->container, PCIE500_CFGDATA, &h->data_mem);
-    memory_region_add_subregion(&s->container, PCIE500_REG_BASE, &s->iomem);
+    memory_region_add_subregion(&s->container, PCIE500_CFGADDR, &h->conf_mem,
+                                &error_abort);
+    memory_region_add_subregion(&s->container, PCIE500_CFGDATA, &h->data_mem,
+                                &error_abort);
+    memory_region_add_subregion(&s->container, PCIE500_REG_BASE, &s->iomem,
+                                &error_abort);
     sysbus_init_mmio(dev, &s->container);
     pci_bus_set_route_irq_fn(b, e500_route_intx_pin_to_irq);
 
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index c63f45d..a5213bc 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -230,19 +230,21 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp)
 
     memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, s,
                           "pci-conf-idx", 4);
-    memory_region_add_subregion(&s->pci_io, 0xcf8, &h->conf_mem);
+    memory_region_add_subregion(&s->pci_io, 0xcf8, &h->conf_mem, &error_abort);
 
     memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, s,
                           "pci-conf-data", 4);
-    memory_region_add_subregion(&s->pci_io, 0xcfc, &h->data_mem);
+    memory_region_add_subregion(&s->pci_io, 0xcfc, &h->data_mem, &error_abort);
 
     memory_region_init_io(&h->mmcfg, OBJECT(s), &raven_pci_io_ops, s,
                           "pciio", 0x00400000);
-    memory_region_add_subregion(address_space_mem, 0x80800000, &h->mmcfg);
+    memory_region_add_subregion(address_space_mem, 0x80800000, &h->mmcfg,
+                                &error_abort);
 
     memory_region_init_io(&s->pci_intack, OBJECT(s), &raven_intack_ops, s,
                           "pci-intack", 1);
-    memory_region_add_subregion(address_space_mem, 0xbffffff0, &s->pci_intack);
+    memory_region_add_subregion(address_space_mem, 0xbffffff0, &s->pci_intack,
+                                &error_abort);
 
     /* TODO Remove once realize propagates to child devices. */
     object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp);
@@ -262,10 +264,12 @@ static void raven_pcihost_initfn(Object *obj)
     address_space_init(&s->pci_io_as, &s->pci_io, "raven-io");
 
     /* CPU address space */
-    memory_region_add_subregion(address_space_mem, 0x80000000, &s->pci_io);
+    memory_region_add_subregion(address_space_mem, 0x80000000, &s->pci_io,
+                                &error_abort);
     memory_region_add_subregion_overlap(address_space_mem, 0x80000000,
                                         &s->pci_io_non_contiguous, 1);
-    memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory);
+    memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory,
+                                &error_abort);
     pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
                         &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
 
@@ -276,8 +280,10 @@ static void raven_pcihost_initfn(Object *obj)
                              memory_region_size(&s->pci_memory));
     memory_region_init_alias(&s->bm_ram_alias, obj, "bm-system",
                              get_system_memory(), 0, 0x80000000);
-    memory_region_add_subregion(&s->bm, 0         , &s->bm_pci_memory_alias);
-    memory_region_add_subregion(&s->bm, 0x80000000, &s->bm_ram_alias);
+    memory_region_add_subregion(&s->bm, 0         , &s->bm_pci_memory_alias,
+                                &error_abort);
+    memory_region_add_subregion(&s->bm, 0x80000000, &s->bm_ram_alias,
+                                &error_abort);
     address_space_init(&s->bm_as, &s->bm, "raven-bm");
     pci_setup_iommu(&s->pci_bus, raven_pcihost_set_iommu, s);
 
@@ -305,7 +311,7 @@ static void raven_realize(PCIDevice *d, Error **errp)
                            &error_abort);
     memory_region_set_readonly(&s->bios, true);
     memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE),
-                                &s->bios);
+                                &s->bios, &error_abort);
     vmstate_register_ram_global(&s->bios);
     if (s->bios_name) {
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, s->bios_name);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index bd74094..d9f8d56 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -494,11 +494,13 @@ static void mch_realize(PCIDevice *d, Error **errp)
     memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
                              mch->ram_memory, 0xa0000, 0x20000);
     memory_region_set_enabled(&mch->low_smram, true);
-    memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
+    memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram,
+                                &error_abort);
     memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high",
                              mch->ram_memory, 0xa0000, 0x20000);
     memory_region_set_enabled(&mch->high_smram, true);
-    memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram);
+    memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram,
+                                &error_abort);
 
     memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch),
                           &tseg_blackhole_ops, NULL,
@@ -512,7 +514,7 @@ static void mch_realize(PCIDevice *d, Error **errp)
                              mch->ram_memory, mch->below_4g_mem_size, 0);
     memory_region_set_enabled(&mch->tseg_window, false);
     memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size,
-                                &mch->tseg_window);
+                                &mch->tseg_window, &error_abort);
     object_property_add_const_link(qdev_get_machine(), "smram",
                                    OBJECT(&mch->smram), &error_abort);
 
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index f0144eb..8604565 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -235,7 +235,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
     memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio,
                              0x80000000ULL, 0x10000000ULL);
     memory_region_add_subregion(address_space_mem, 0x80000000ULL,
-                                &d->pci_hole);
+                                &d->pci_hole, &error_abort);
 
     h->bus = pci_register_bus(dev, NULL,
                               pci_unin_set_irq, pci_unin_map_irq,
@@ -301,7 +301,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
     memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio,
                              0x80000000ULL, 0x70000000ULL);
     memory_region_add_subregion(address_space_mem, 0x80000000ULL,
-                                &d->pci_hole);
+                                &d->pci_hole, &error_abort);
 
     h->bus = pci_register_bus(dev, NULL,
                               pci_unin_set_irq, pci_unin_map_irq,
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 7716bf3..10faae6 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -282,10 +282,12 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
 
     memory_region_init_io(&dev->msix_table_mmio, OBJECT(dev), &msix_table_mmio_ops, dev,
                           "msix-table", table_size);
-    memory_region_add_subregion(table_bar, table_offset, &dev->msix_table_mmio);
+    memory_region_add_subregion(table_bar, table_offset, &dev->msix_table_mmio,
+                                &error_abort);
     memory_region_init_io(&dev->msix_pba_mmio, OBJECT(dev), &msix_pba_mmio_ops, dev,
                           "msix-pba", pba_size);
-    memory_region_add_subregion(pba_bar, pba_offset, &dev->msix_pba_mmio);
+    memory_region_add_subregion(pba_bar, pba_offset, &dev->msix_pba_mmio,
+                                &error_abort);
 
     return 0;
 }
diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index d8afba8..432088e 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -114,7 +114,8 @@ void pcie_host_mmcfg_map(PCIExpressHost *e, hwaddr addr,
 {
     pcie_host_mmcfg_init(e, size);
     e->base_addr = addr;
-    memory_region_add_subregion(get_system_memory(), e->base_addr, &e->mmio);
+    memory_region_add_subregion(get_system_memory(), e->base_addr, &e->mmio,
+                                &error_abort);
 }
 
 void pcie_host_mmcfg_update(PCIExpressHost *e,
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index bfb4d31..fae1542 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -644,7 +644,7 @@ int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar, unsigned offset)
     memory_region_init_io(&shpc->mmio, OBJECT(d), &shpc_mmio_ops,
                           d, "shpc-mmio", SHPC_SIZEOF(d));
     shpc_cap_update_dword(d);
-    memory_region_add_subregion(bar, offset, &shpc->mmio);
+    memory_region_add_subregion(bar, offset, &shpc->mmio, &error_abort);
 
     qbus_set_hotplug_handler(BUS(sec_bus), DEVICE(d), NULL);
 
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
index a7e1877..3728c72 100644
--- a/hw/pcmcia/pxa2xx.c
+++ b/hw/pcmcia/pxa2xx.c
@@ -166,7 +166,7 @@ static void pxa2xx_pcmcia_initfn(Object *obj)
     memory_region_init_io(&s->iomem, NULL, &pxa2xx_pcmcia_io_ops, s,
                           "pxa2xx-pcmcia-io", 0x04000000);
     memory_region_add_subregion(&s->container_mem, 0x00000000,
-                                &s->iomem);
+                                &s->iomem, &error_abort);
 
     /* Then next 64 MB is reserved */
 
@@ -174,13 +174,13 @@ static void pxa2xx_pcmcia_initfn(Object *obj)
     memory_region_init_io(&s->attr_iomem, NULL, &pxa2xx_pcmcia_attr_ops, s,
                           "pxa2xx-pcmcia-attribute", 0x04000000);
     memory_region_add_subregion(&s->container_mem, 0x08000000,
-                                &s->attr_iomem);
+                                &s->attr_iomem, &error_abort);
 
     /* Socket Common Memory Space */
     memory_region_init_io(&s->common_iomem, NULL, &pxa2xx_pcmcia_common_ops, s,
                           "pxa2xx-pcmcia-common", 0x04000000);
     memory_region_add_subregion(&s->container_mem, 0x0c000000,
-                                &s->common_iomem);
+                                &s->common_iomem, &error_abort);
 
     s->slot.irq = qemu_allocate_irq(pxa2xx_pcmcia_set_irq, s, 0);
 
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index d300846..8aeebc1 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -767,7 +767,7 @@ static qemu_irq *ppce500_init_mpic(MachineState *machine, PPCE500Params *params,
 
     s = SYS_BUS_DEVICE(dev);
     memory_region_add_subregion(ccsr, MPC8544_MPIC_REGS_OFFSET,
-                                s->mmio[0].memory);
+                                s->mmio[0].memory, &error_abort);
 
     return mpic;
 }
@@ -863,7 +863,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
 
     /* Register Memory */
     memory_region_allocate_system_memory(ram, NULL, "mpc8544ds.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
 
     dev = qdev_create(NULL, "e500-ccsr");
     object_property_add_child(qdev_get_machine(), "e500-ccsr",
@@ -872,7 +872,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
     ccsr = CCSR(dev);
     ccsr_addr_space = &ccsr->ccsr_space;
     memory_region_add_subregion(address_space_mem, params->ccsrbar_base,
-                                ccsr_addr_space);
+                                ccsr_addr_space, &error_abort);
 
     mpic = ppce500_init_mpic(machine, params, ccsr_addr_space, irqs);
 
@@ -894,7 +894,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
     qdev_init_nofail(dev);
     s = SYS_BUS_DEVICE(dev);
     memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET,
-                                sysbus_mmio_get_region(s, 0));
+                                sysbus_mmio_get_region(s, 0), &error_abort);
 
     /* PCI */
     dev = qdev_create(NULL, "e500-pcihost");
@@ -907,7 +907,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
     }
 
     memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET,
-                                sysbus_mmio_get_region(s, 0));
+                                sysbus_mmio_get_region(s, 0), &error_abort);
 
     pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
     if (!pci_bus)
@@ -936,7 +936,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
         qdev_init_nofail(dev);
         sysbus_connect_irq(s, 0, mpic[MPC8XXX_GPIO_IRQ]);
         memory_region_add_subregion(ccsr_addr_space, MPC8XXX_GPIO_OFFSET,
-                                    sysbus_mmio_get_region(s, 0));
+                                    sysbus_mmio_get_region(s, 0), &error_abort);
 
         /* Power Off GPIO at Pin 0 */
         poweroff_irq = qemu_allocate_irq(ppce500_power_off, NULL, 0);
@@ -959,7 +959,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
 
         memory_region_add_subregion(address_space_mem,
                                     params->platform_bus_base,
-                                    sysbus_mmio_get_region(s, 0));
+                                    sysbus_mmio_get_region(s, 0), &error_abort);
     }
 
     /* Load kernel. */
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 0f3e341..a854926 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -203,7 +203,7 @@ static void ppc_core99_init(MachineState *machine)
 
     /* allocate RAM */
     memory_region_allocate_system_memory(ram, NULL, "ppc_core99.ram", ram_size);
-    memory_region_add_subregion(get_system_memory(), 0, ram);
+    memory_region_add_subregion(get_system_memory(), 0, ram, &error_abort);
 
     /* allocate and load BIOS */
     memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE,
@@ -214,7 +214,8 @@ static void ppc_core99_init(MachineState *machine)
         bios_name = PROM_FILENAME;
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     memory_region_set_readonly(bios, true);
-    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);
+    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios,
+                                &error_abort);
 
     /* Load OpenBIOS (ELF) */
     if (filename) {
@@ -296,14 +297,17 @@ static void ppc_core99_init(MachineState *machine)
     /* Register 8 MB of ISA IO space */
     memory_region_init_alias(isa, NULL, "isa_mmio",
                              get_system_io(), 0, 0x00800000);
-    memory_region_add_subregion(get_system_memory(), 0xf2000000, isa);
+    memory_region_add_subregion(get_system_memory(), 0xf2000000, isa,
+                                &error_abort);
 
     /* UniN init: XXX should be a real device */
     memory_region_init_io(unin_memory, NULL, &unin_ops, token, "unin", 0x1000);
-    memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);
+    memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory,
+                                &error_abort);
 
     memory_region_init_io(unin2_memory, NULL, &unin_ops, token, "unin", 0x1000);
-    memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory);
+    memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory,
+                                &error_abort);
 
     openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
     openpic_irqs[0] =
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 99879dd..5118202 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -132,7 +132,7 @@ static void ppc_heathrow_init(MachineState *machine)
 
     memory_region_allocate_system_memory(ram, NULL, "ppc_heathrow.ram",
                                          ram_size);
-    memory_region_add_subregion(sysmem, 0, ram);
+    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
 
     /* allocate and load BIOS */
     memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE,
@@ -143,7 +143,7 @@ static void ppc_heathrow_init(MachineState *machine)
         bios_name = PROM_FILENAME;
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     memory_region_set_readonly(bios, true);
-    memory_region_add_subregion(sysmem, PROM_ADDR, bios);
+    memory_region_add_subregion(sysmem, PROM_ADDR, bios, &error_abort);
 
     /* Load OpenBIOS (ELF) */
     if (filename) {
@@ -232,7 +232,7 @@ static void ppc_heathrow_init(MachineState *machine)
     /* Register 2 MB of ISA IO space */
     memory_region_init_alias(isa, NULL, "isa_mmio",
                              get_system_io(), 0, 0x00200000);
-    memory_region_add_subregion(sysmem, 0xfe000000, isa);
+    memory_region_add_subregion(sysmem, 0xfe000000, isa, &error_abort);
 
     /* XXX: we register only 1 output pin for heathrow PIC */
     heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index ec6c4cb..80144e0 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -169,7 +169,7 @@ static void ref405ep_fpga_init(MemoryRegion *sysmem, uint32_t base)
     fpga = g_malloc0(sizeof(ref405ep_fpga_t));
     memory_region_init_io(fpga_memory, NULL, &ref405ep_fpga_ops, fpga,
                           "fpga", 0x00000100);
-    memory_region_add_subregion(sysmem, base, fpga_memory);
+    memory_region_add_subregion(sysmem, base, fpga_memory, &error_abort);
     qemu_register_reset(&ref405ep_fpga_reset, fpga);
 }
 
@@ -217,7 +217,7 @@ static void ref405ep_init(MachineState *machine)
     sram_size = 512 * 1024;
     memory_region_init_ram(sram, NULL, "ef405ep.sram", sram_size, &error_abort);
     vmstate_register_ram_global(sram);
-    memory_region_add_subregion(sysmem, 0xFFF00000, sram);
+    memory_region_add_subregion(sysmem, 0xFFF00000, sram, &error_abort);
     /* allocate and load BIOS */
 #ifdef DEBUG_BOARD_INIT
     printf("%s: register BIOS\n", __func__);
@@ -264,7 +264,8 @@ static void ref405ep_init(MachineState *machine)
                 exit(1);
             }
             bios_size = (bios_size + 0xfff) & ~0xfff;
-            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
+            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios,
+                                        &error_abort);
         } else if (!qtest_enabled() || kernel_filename != NULL) {
             error_report("Could not load PowerPC BIOS '%s'", bios_name);
             exit(1);
@@ -500,7 +501,7 @@ static void taihu_cpld_init(MemoryRegion *sysmem, uint32_t base)
 
     cpld = g_malloc0(sizeof(taihu_cpld_t));
     memory_region_init_io(cpld_memory, NULL, &taihu_cpld_ops, cpld, "cpld", 0x100);
-    memory_region_add_subregion(sysmem, base, cpld_memory);
+    memory_region_add_subregion(sysmem, base, cpld_memory, &error_abort);
     qemu_register_reset(&taihu_cpld_reset, cpld);
 }
 
@@ -590,7 +591,8 @@ static void taihu_405ep_init(MachineState *machine)
                 exit(1);
             }
             bios_size = (bios_size + 0xfff) & ~0xfff;
-            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
+            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios,
+                                        &error_abort);
         } else if (!qtest_enabled()) {
             error_report("Could not load PowerPC BIOS '%s'", bios_name);
             exit(1);
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index c77434a..d33a2f6 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -393,7 +393,8 @@ static void ppc4xx_opba_init(hwaddr base)
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
     memory_region_init_io(&opba->io, NULL, &opba_ops, opba, "opba", 0x002);
-    memory_region_add_subregion(get_system_memory(), base, &opba->io);
+    memory_region_add_subregion(get_system_memory(), base, &opba->io,
+                                &error_abort);
     qemu_register_reset(ppc4xx_opba_reset, opba);
 }
 
@@ -815,7 +816,8 @@ static void ppc405_gpio_init(hwaddr base)
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
     memory_region_init_io(&gpio->io, NULL, &ppc405_gpio_ops, gpio, "pgio", 0x038);
-    memory_region_add_subregion(get_system_memory(), base, &gpio->io);
+    memory_region_add_subregion(get_system_memory(), base, &gpio->io,
+                                &error_abort);
     qemu_register_reset(&ppc405_gpio_reset, gpio);
 }
 
@@ -863,7 +865,7 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
             printf("OCM map ISA %08" PRIx32 "\n", isarc);
 #endif
             memory_region_add_subregion(get_system_memory(), isarc,
-                                        &ocm->isarc_ram);
+                                        &ocm->isarc_ram, &error_abort);
         }
     }
     if (ocm->dsarc != dsarc ||
@@ -887,7 +889,7 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
                 printf("OCM map DSA %08" PRIx32 "\n", dsarc);
 #endif
                 memory_region_add_subregion(get_system_memory(), dsarc,
-                                            &ocm->dsarc_ram);
+                                            &ocm->dsarc_ram, &error_abort);
             }
         }
     }
@@ -1226,7 +1228,8 @@ static void ppc405_i2c_init(hwaddr base, qemu_irq irq)
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
     memory_region_init_io(&i2c->iomem, NULL, &i2c_ops, i2c, "i2c", 0x011);
-    memory_region_add_subregion(get_system_memory(), base, &i2c->iomem);
+    memory_region_add_subregion(get_system_memory(), base, &i2c->iomem,
+                                &error_abort);
     qemu_register_reset(ppc4xx_i2c_reset, i2c);
 }
 
@@ -1505,7 +1508,8 @@ static void ppc4xx_gpt_init(hwaddr base, qemu_irq irqs[5])
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
     memory_region_init_io(&gpt->iomem, NULL, &gpt_ops, gpt, "gpt", 0x0d4);
-    memory_region_add_subregion(get_system_memory(), base, &gpt->iomem);
+    memory_region_add_subregion(get_system_memory(), base, &gpt->iomem,
+                                &error_abort);
     qemu_register_reset(ppc4xx_gpt_reset, gpt);
 }
 
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 778970a..bc37d8a 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -229,7 +229,8 @@ static void bamboo_init(MachineState *machine)
 
     memory_region_init_alias(isa, NULL, "isa_mmio",
                              get_system_io(), 0, PPC440EP_PCI_IOLEN);
-    memory_region_add_subregion(get_system_memory(), PPC440EP_PCI_IO, isa);
+    memory_region_add_subregion(get_system_memory(), PPC440EP_PCI_IO, isa,
+                                &error_abort);
 
     if (serial_hds[0] != NULL) {
         serial_mm_init(address_space_mem, 0xef600300, 0, pic[0],
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 2f38ff7..efd88e0 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -433,10 +433,10 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram,
         memory_region_init(&sdram->containers[n], NULL, "sdram-containers",
                            sdram_size(bcr));
         memory_region_add_subregion(&sdram->containers[n], 0,
-                                    &sdram->ram_memories[n]);
+                                    &sdram->ram_memories[n], &error_abort);
         memory_region_add_subregion(get_system_memory(),
                                     sdram_base(bcr),
-                                    &sdram->containers[n]);
+                                    &sdram->containers[n], &error_abort);
     }
 }
 
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 0bb3cdb..ddd6845 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -335,9 +335,12 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
                           "pci-conf-data", 4);
     memory_region_init_io(&s->iomem, OBJECT(s), &pci_reg_ops, s,
                           "pci.reg", PCI_REG_SIZE);
-    memory_region_add_subregion(&s->container, PCIC0_CFGADDR, &h->conf_mem);
-    memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem);
-    memory_region_add_subregion(&s->container, PCI_REG_BASE, &s->iomem);
+    memory_region_add_subregion(&s->container, PCIC0_CFGADDR, &h->conf_mem,
+                                &error_abort);
+    memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem,
+                                &error_abort);
+    memory_region_add_subregion(&s->container, PCI_REG_BASE, &s->iomem,
+                                &error_abort);
     sysbus_init_mmio(dev, &s->container);
     qemu_register_reset(ppc4xx_pci_reset, s);
 
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 998ee2d..1e9758b 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -558,7 +558,7 @@ static void ppc_prep_init(MachineState *machine)
 
     /* allocate RAM */
     memory_region_allocate_system_memory(ram, NULL, "ppc_prep.ram", ram_size);
-    memory_region_add_subregion(sysmem, 0, ram);
+    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
 
     if (linux_boot) {
         kernel_base = KERNEL_LOAD_ADDR;
@@ -676,7 +676,7 @@ static void ppc_prep_init(MachineState *machine)
     /* PowerPC control and status register group */
 #if 0
     memory_region_init_io(xcsr, NULL, &PPC_XCSR_ops, NULL, "ppc-xcsr", 0x1000);
-    memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr);
+    memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr, &error_abort);
 #endif
 
     if (usb_enabled()) {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f174e5a..de237fc 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1515,14 +1515,14 @@ static void ppc_spapr_init(MachineState *machine)
     spapr->ram_limit = ram_size;
     memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram",
                                          spapr->ram_limit);
-    memory_region_add_subregion(sysmem, 0, ram);
+    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
 
     if (rma_alloc_size && rma) {
         rma_region = g_new(MemoryRegion, 1);
         memory_region_init_ram_ptr(rma_region, NULL, "ppc_spapr.rma",
                                    rma_alloc_size, rma);
         vmstate_register_ram_global(rma_region);
-        memory_region_add_subregion(sysmem, 0, rma_region);
+        memory_region_add_subregion(sysmem, 0, rma_region, &error_abort);
     }
 
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index d4a6150..03fb6c1 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1183,7 +1183,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
                              namebuf, &sphb->memspace,
                              SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size);
     memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,
-                                &sphb->memwindow);
+                                &sphb->memwindow, &error_abort);
 
     /* Initialize IO regions */
     sprintf(namebuf, "%s.io", sphb->dtbusname);
@@ -1194,7 +1194,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
     memory_region_init_alias(&sphb->iowindow, OBJECT(sphb), namebuf,
                              &sphb->iospace, 0, SPAPR_PCI_IO_WIN_SIZE);
     memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
-                                &sphb->iowindow);
+                                &sphb->iowindow, &error_abort);
 
     bus = pci_register_bus(dev, NULL,
                            pci_spapr_set_irq, pci_spapr_map_irq, sphb,
@@ -1237,7 +1237,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
     memory_region_init_io(&sphb->msiwindow, NULL, &spapr_msi_ops, spapr,
                           "msi", msi_window_size);
     memory_region_add_subregion(&sphb->iommu_root, SPAPR_PCI_MSI_WINDOW,
-                                &sphb->msiwindow);
+                                &sphb->msiwindow, &error_abort);
 
     pci_setup_iommu(bus, spapr_pci_dma_iommu, sphb);
 
@@ -1293,7 +1293,7 @@ static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp)
 
     /* Register default 32bit DMA window */
     memory_region_add_subregion(&sphb->iommu_root, 0,
-                                spapr_tce_get_iommu(tcet));
+                                spapr_tce_get_iommu(tcet), &error_abort);
 }
 
 static int spapr_phb_children_reset(Object *child, void *opaque)
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 99a1be5..6b9e2af 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -68,7 +68,7 @@ static void spapr_phb_vfio_finish_realize(sPAPRPHBState *sphb, Error **errp)
 
     /* Register default 32bit DMA window */
     memory_region_add_subregion(&sphb->iommu_root, tcet->bus_offset,
-                                spapr_tce_get_iommu(tcet));
+                                spapr_tce_get_iommu(tcet), &error_abort);
 }
 
 static void spapr_phb_vfio_reset(DeviceState *qdev)
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 439732f..1db90d5 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -223,7 +223,8 @@ static void virtex_init(MachineState *machine)
     qemu_register_reset(main_cpu_reset, cpu);
 
     memory_region_allocate_system_memory(phys_ram, NULL, "ram", ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    memory_region_add_subregion(address_space_mem, ram_base, phys_ram,
+                                &error_abort);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE,
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 3d20d6a..1ee08c3 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -162,7 +162,7 @@ static void ccw_init(MachineState *machine)
     /* allocate RAM for core */
     memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size, &error_abort);
     vmstate_register_ram_global(ram);
-    memory_region_add_subregion(sysmem, 0, ram);
+    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
 
     /* If the size of ram is not on a MEM_SECTION_SIZE boundary,
        calculate the pad size necessary to force this boundary. */
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 1284e77..7d61bfb 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -295,7 +295,7 @@ static void s390_init(MachineState *machine)
     /* allocate RAM */
     memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size, &error_abort);
     vmstate_register_ram_global(ram);
-    memory_region_add_subregion(sysmem, 0, ram);
+    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
 
     /* clear virtio region */
     virtio_region_len = my_ram_size - ram_size;
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index b3a6c5e..db461b8 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -243,7 +243,8 @@ static void assign_storage(SCCB *sccb)
 
             memory_region_init_ram(standby_ram, NULL, id, this_subregion_size, &error_abort);
             vmstate_register_ram_global(standby_ram);
-            memory_region_add_subregion(sysmem, offset, standby_ram);
+            memory_region_add_subregion(sysmem, offset, standby_ram,
+                                        &error_abort);
         }
         /* The specified subregion is no longer in standby */
         mhd->standby_state_map[(assign_addr - mhd->padded_ram_size)
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
index d072dec..63b6b7d 100644
--- a/hw/sd/omap_mmc.c
+++ b/hw/sd/omap_mmc.c
@@ -590,7 +590,7 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
     omap_mmc_reset(s);
 
     memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc", 0x800);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     /* Instantiate the storage */
     s->card = sd_init(blk, false);
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
index d1fe6d5..fcad7df 100644
--- a/hw/sd/pxa2xx_mmci.c
+++ b/hw/sd/pxa2xx_mmci.c
@@ -483,7 +483,7 @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
 
     memory_region_init_io(&s->iomem, NULL, &pxa2xx_mmci_ops, s,
                           "pxa2xx-mmci", 0x00100000);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
 
     /* Instantiate the actual storage */
     s->card = sd_init(blk, false);
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 5e22ed7..96124fe 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -187,7 +187,7 @@ static qemu_irq *r2d_fpga_init(MemoryRegion *sysmem,
     s->irl = irl;
 
     memory_region_init_io(&s->iomem, NULL, &r2d_fpga_ops, s, "r2d-fpga", 0x40);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
     return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
 }
 
@@ -257,7 +257,8 @@ static void r2d_init(MachineState *machine)
     /* Allocate memory space */
     memory_region_init_ram(sdram, NULL, "r2d.sdram", SDRAM_SIZE, &error_abort);
     vmstate_register_ram_global(sdram);
-    memory_region_add_subregion(address_space_mem, SDRAM_BASE, sdram);
+    memory_region_add_subregion(address_space_mem, SDRAM_BASE, sdram,
+                                &error_abort);
     /* Register peripherals */
     s = sh7750_init(cpu, address_space_mem);
     irq = r2d_fpga_init(address_space_mem, 0x04000000, sh7750_irl(s));
diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c
index 5dda5de..e0a283f 100644
--- a/hw/sh4/sh7750.c
+++ b/hw/sh4/sh7750.c
@@ -735,31 +735,38 @@ SH7750State *sh7750_init(SuperHCPU *cpu, MemoryRegion *sysmem)
 
     memory_region_init_alias(&s->iomem_1f0, NULL, "memory-1f0",
                              &s->iomem, 0x1f000000, 0x1000);
-    memory_region_add_subregion(sysmem, 0x1f000000, &s->iomem_1f0);
+    memory_region_add_subregion(sysmem, 0x1f000000, &s->iomem_1f0,
+                                &error_abort);
 
     memory_region_init_alias(&s->iomem_ff0, NULL, "memory-ff0",
                              &s->iomem, 0x1f000000, 0x1000);
-    memory_region_add_subregion(sysmem, 0xff000000, &s->iomem_ff0);
+    memory_region_add_subregion(sysmem, 0xff000000, &s->iomem_ff0,
+                                &error_abort);
 
     memory_region_init_alias(&s->iomem_1f8, NULL, "memory-1f8",
                              &s->iomem, 0x1f800000, 0x1000);
-    memory_region_add_subregion(sysmem, 0x1f800000, &s->iomem_1f8);
+    memory_region_add_subregion(sysmem, 0x1f800000, &s->iomem_1f8,
+                                &error_abort);
 
     memory_region_init_alias(&s->iomem_ff8, NULL, "memory-ff8",
                              &s->iomem, 0x1f800000, 0x1000);
-    memory_region_add_subregion(sysmem, 0xff800000, &s->iomem_ff8);
+    memory_region_add_subregion(sysmem, 0xff800000, &s->iomem_ff8,
+                                &error_abort);
 
     memory_region_init_alias(&s->iomem_1fc, NULL, "memory-1fc",
                              &s->iomem, 0x1fc00000, 0x1000);
-    memory_region_add_subregion(sysmem, 0x1fc00000, &s->iomem_1fc);
+    memory_region_add_subregion(sysmem, 0x1fc00000, &s->iomem_1fc,
+                                &error_abort);
 
     memory_region_init_alias(&s->iomem_ffc, NULL, "memory-ffc",
                              &s->iomem, 0x1fc00000, 0x1000);
-    memory_region_add_subregion(sysmem, 0xffc00000, &s->iomem_ffc);
+    memory_region_add_subregion(sysmem, 0xffc00000, &s->iomem_ffc,
+                                &error_abort);
 
     memory_region_init_io(&s->mmct_iomem, NULL, &sh7750_mmct_ops, s,
                           "cache-and-tlb", 0x08000000);
-    memory_region_add_subregion(sysmem, 0xf0000000, &s->mmct_iomem);
+    memory_region_add_subregion(sysmem, 0xf0000000, &s->mmct_iomem,
+                                &error_abort);
 
     sh_intc_init(sysmem, &s->intc, NR_SOURCES,
 		 _INTC_ARRAY(mask_registers),
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index a2f6d9e..68b989e 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -67,7 +67,8 @@ static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
             memory_region_del_subregion(get_system_memory(), &pcic->isa);
             pcic->iobr = val & 0xfffc0001;
             memory_region_add_subregion(get_system_memory(),
-                                        pcic->iobr & 0xfffc0000, &pcic->isa);
+                                        pcic->iobr & 0xfffc0000, &pcic->isa,
+                                        &error_abort);
         }
         break;
     case 0x220:
@@ -145,7 +146,8 @@ static int sh_pci_device_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->memconfig_p4);
     sysbus_init_mmio(dev, &s->memconfig_a7);
     s->iobr = 0xfe240000;
-    memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
+    memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa,
+                                &error_abort);
 
     s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
     return 0;
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index f93f98e..b6f7af3 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -62,15 +62,15 @@ static void shix_init(MachineState *machine)
     memory_region_init_ram(rom, NULL, "shix.rom", 0x4000, &error_abort);
     vmstate_register_ram_global(rom);
     memory_region_set_readonly(rom, true);
-    memory_region_add_subregion(sysmem, 0x00000000, rom);
+    memory_region_add_subregion(sysmem, 0x00000000, rom, &error_abort);
     memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000,
                            &error_abort);
     vmstate_register_ram_global(&sdram[0]);
-    memory_region_add_subregion(sysmem, 0x08000000, &sdram[0]);
+    memory_region_add_subregion(sysmem, 0x08000000, &sdram[0], &error_abort);
     memory_region_init_ram(&sdram[1], NULL, "shix.sdram2", 0x01000000,
                            &error_abort);
     vmstate_register_ram_global(&sdram[1]);
-    memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);
+    memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1], &error_abort);
 
     /* Load BIOS in 0 (and access it through P2, 0xA0000000) */
     if (bios_name == NULL)
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 7f5dcd6..2103bd7 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -152,14 +152,16 @@ static void leon3_generic_hw_init(MachineState *machine)
     }
 
     memory_region_allocate_system_memory(ram, NULL, "leon3.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
+    memory_region_add_subregion(address_space_mem, 0x40000000, ram,
+                                &error_abort);
 
     /* Allocate BIOS */
     prom_size = 8 * 1024 * 1024; /* 8Mb */
     memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size, &error_abort);
     vmstate_register_ram_global(prom);
     memory_region_set_readonly(prom, true);
-    memory_region_add_subregion(address_space_mem, 0x00000000, prom);
+    memory_region_add_subregion(address_space_mem, 0x00000000, prom,
+                                &error_abort);
 
     /* Load boot prom */
     if (bios_name == NULL) {
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 30cfa0e..7252c83 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -874,7 +874,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59);
     s = SYS_BUS_DEVICE(nvram);
     memory_region_add_subregion(get_system_io(), 0x2000,
-                                sysbus_mmio_get_region(s, 0));
+                                sysbus_mmio_get_region(s, 0), &error_abort);
  
     initrd_size = 0;
     initrd_addr = 0;
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 8ab683d..89bb5a6 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -698,7 +698,8 @@ Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
         sysbus_connect_irq(s, 0, IRQ);
         if (io_base != 0) {
             memory_region_add_subregion(get_system_io(), io_base,
-                                        sysbus_mmio_get_region(s, 1));
+                                        sysbus_mmio_get_region(s, 1),
+                                        &error_abort);
         }
         if (mem_base != 0) {
             sysbus_mmio_map(s, 0, mem_base);
diff --git a/hw/timer/sh_timer.c b/hw/timer/sh_timer.c
index 07f0670..40ed41c 100644
--- a/hw/timer/sh_timer.c
+++ b/hw/timer/sh_timer.c
@@ -325,10 +325,12 @@ void tmu012_init(MemoryRegion *sysmem, hwaddr base,
 
     memory_region_init_alias(&s->iomem_p4, NULL, "timer-p4",
                              &s->iomem, 0, 0x1000);
-    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4);
+    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4,
+                                &error_abort);
 
     memory_region_init_alias(&s->iomem_a7, NULL, "timer-a7",
                              &s->iomem, 0, 0x1000);
-    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7);
+    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7,
+                                &error_abort);
     /* ??? Save/restore.  */
 }
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 0806b5f..3312bce 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1060,7 +1060,7 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
     isa_init_irq(&s->busdev, &tis->irq, tis->irq_num);
 
     memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),
-                                TPM_TIS_ADDR_BASE, &s->mmio);
+                                TPM_TIS_ADDR_BASE, &s->mmio, &error_abort);
 }
 
 static void tpm_tis_initfn(Object *obj)
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
index a059a20..14290af 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -89,12 +89,12 @@ static void tricore_testboard_init(MachineState *machine, int board_id)
     memory_region_init_ram(pcp_text, NULL, "powerlink_pcp_text.ram", 32*1024, &error_abort);
     vmstate_register_ram_global(pcp_text);
 
-    memory_region_add_subregion(sysmem, 0x80000000, ext_cram);
-    memory_region_add_subregion(sysmem, 0xa1000000, ext_dram);
-    memory_region_add_subregion(sysmem, 0xd4000000, int_cram);
-    memory_region_add_subregion(sysmem, 0xd0000000, int_dram);
-    memory_region_add_subregion(sysmem, 0xf0050000, pcp_data);
-    memory_region_add_subregion(sysmem, 0xf0060000, pcp_text);
+    memory_region_add_subregion(sysmem, 0x80000000, ext_cram, &error_abort);
+    memory_region_add_subregion(sysmem, 0xa1000000, ext_dram, &error_abort);
+    memory_region_add_subregion(sysmem, 0xd4000000, int_cram, &error_abort);
+    memory_region_add_subregion(sysmem, 0xd0000000, int_dram, &error_abort);
+    memory_region_add_subregion(sysmem, 0xf0050000, pcp_data, &error_abort);
+    memory_region_add_subregion(sysmem, 0xf0060000, pcp_text, &error_abort);
 
     tricoretb_binfo.ram_size = machine->ram_size;
     tricoretb_binfo.kernel_filename = machine->kernel_filename;
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 703e29d..23ffc39 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -66,7 +66,8 @@ static void puv3_soc_init(CPUUniCore32State *env)
 
     /* Keyboard (i8042), mouse disabled for nographic */
     i8042_mm_init(irqs[PUV3_IRQS_PS2_KBD], NULL, i8042, PUV3_REGS_OFFSET, 4);
-    memory_region_add_subregion(get_system_memory(), PUV3_PS2_BASE, i8042);
+    memory_region_add_subregion(get_system_memory(), PUV3_PS2_BASE, i8042,
+                                &error_abort);
 }
 
 static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
@@ -77,7 +78,8 @@ static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
     memory_region_init_ram(ram_memory, NULL, "puv3.ram", ram_size,
                            &error_abort);
     vmstate_register_ram_global(ram_memory);
-    memory_region_add_subregion(get_system_memory(), 0, ram_memory);
+    memory_region_add_subregion(get_system_memory(), 0, ram_memory,
+                                &error_abort);
 }
 
 static const GraphicHwOps no_ops;
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index cd1cc14..c487cec 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -194,7 +194,7 @@ static void fusbh200_ehci_init(Object *obj)
                           "fusbh200", 0x4c);
     memory_region_add_subregion(&s->mem,
                                 s->opregbase + s->portscbase + 4 * s->portnr,
-                                &f->mem_vendor);
+                                &f->mem_vendor, &error_abort);
 }
 
 static void fusbh200_ehci_class_init(ObjectClass *oc, void *data)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index d7cd40b..2f3f960 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2522,10 +2522,12 @@ void usb_ehci_init(EHCIState *s, DeviceState *dev)
     memory_region_init_io(&s->mem_ports, OBJECT(dev), &ehci_mmio_port_ops, s,
                           "ports", 4 * s->portnr);
 
-    memory_region_add_subregion(&s->mem, s->capsbase, &s->mem_caps);
-    memory_region_add_subregion(&s->mem, s->opregbase, &s->mem_opreg);
+    memory_region_add_subregion(&s->mem, s->capsbase, &s->mem_caps,
+                                &error_abort);
+    memory_region_add_subregion(&s->mem, s->opregbase, &s->mem_opreg,
+                                &error_abort);
     memory_region_add_subregion(&s->mem, s->opregbase + s->portscbase,
-                                &s->mem_ports);
+                                &s->mem_ports, &error_abort);
 }
 
 /*
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 90a5fbf..efe29ca 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3622,10 +3622,14 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
     memory_region_init_io(&xhci->mem_doorbell, OBJECT(xhci), &xhci_doorbell_ops, xhci,
                           "doorbell", LEN_DOORBELL);
 
-    memory_region_add_subregion(&xhci->mem, 0,            &xhci->mem_cap);
-    memory_region_add_subregion(&xhci->mem, OFF_OPER,     &xhci->mem_oper);
-    memory_region_add_subregion(&xhci->mem, OFF_RUNTIME,  &xhci->mem_runtime);
-    memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell);
+    memory_region_add_subregion(&xhci->mem, 0,            &xhci->mem_cap,
+                                &error_abort);
+    memory_region_add_subregion(&xhci->mem, OFF_OPER,     &xhci->mem_oper,
+                                &error_abort);
+    memory_region_add_subregion(&xhci->mem, OFF_RUNTIME,  &xhci->mem_runtime,
+                                &error_abort);
+    memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell,
+                                &error_abort);
 
     for (i = 0; i < xhci->numports; i++) {
         XHCIPort *port = &xhci->ports[i];
@@ -3633,7 +3637,8 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
         port->xhci = xhci;
         memory_region_init_io(&port->mem, OBJECT(xhci), &xhci_port_ops, port,
                               port->name, 0x10);
-        memory_region_add_subregion(&xhci->mem, offset, &port->mem);
+        memory_region_add_subregion(&xhci->mem, offset, &port->mem,
+                                    &error_abort);
     }
 
     pci_register_bar(dev, 0,
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 85ee9b0..51aea6d 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -525,7 +525,7 @@ empty_region:
         memory_region_init(submem, obj, name, 0);
     }
 
-    memory_region_add_subregion(mem, offset, submem);
+    memory_region_add_subregion(mem, offset, submem, &error_abort);
 
     return ret;
 }
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 2ed877f..f266567 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1430,7 +1430,8 @@ static void vfio_vga_probe_ati_3c3_quirk(VFIOPCIDevice *vdev)
     memory_region_init_io(&quirk->mem, OBJECT(vdev), &vfio_ati_3c3_quirk, quirk,
                           "vfio-ati-3c3-quirk", 1);
     memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,
-                                3 /* offset 3 bytes from 0x3c0 */, &quirk->mem);
+                                3 /* offset 3 bytes from 0x3c0 */, &quirk->mem,
+                                &error_abort);
 
     QLIST_INSERT_HEAD(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks,
                       quirk, next);
@@ -1785,7 +1786,8 @@ static void vfio_vga_probe_nvidia_3d0_quirk(VFIOPCIDevice *vdev)
     memory_region_init_io(&quirk->mem, OBJECT(vdev), &vfio_nvidia_3d0_quirk,
                           quirk, "vfio-nvidia-3d0-quirk", 6);
     memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,
-                                quirk->data.base_offset, &quirk->mem);
+                                quirk->data.base_offset, &quirk->mem,
+                                &error_abort);
 
     QLIST_INSERT_HEAD(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks,
                       quirk, next);
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 7a89081..9c95c74 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1279,7 +1279,8 @@ static void virtio_pci_modern_region_map(VirtIOPCIProxy *proxy,
 {
     memory_region_add_subregion(&proxy->modern_bar,
                                 region->offset,
-                                &region->mr);
+                                &region->mr,
+                                &error_abort);
 
     cap->cfg_type = region->type;
     cap->bar = proxy->modern_mem_bar;
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index 328d209..3da7ca4 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -81,12 +81,13 @@ static void xtensa_sim_init(MachineState *machine)
     ram = g_malloc(sizeof(*ram));
     memory_region_init_ram(ram, NULL, "xtensa.sram", ram_size, &error_abort);
     vmstate_register_ram_global(ram);
-    memory_region_add_subregion(get_system_memory(), 0, ram);
+    memory_region_add_subregion(get_system_memory(), 0, ram, &error_abort);
 
     rom = g_malloc(sizeof(*rom));
     memory_region_init_ram(rom, NULL, "xtensa.rom", 0x1000, &error_abort);
     vmstate_register_ram_global(rom);
-    memory_region_add_subregion(get_system_memory(), 0xfe000000, rom);
+    memory_region_add_subregion(get_system_memory(), 0xfe000000, rom,
+                                &error_abort);
 
     if (kernel_filename) {
         uint64_t elf_entry;
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index ab4d0e4..40bfb81 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -115,7 +115,7 @@ static Lx60FpgaState *lx60_fpga_init(MemoryRegion *address_space,
 
     memory_region_init_io(&s->iomem, NULL, &lx60_fpga_ops, s,
             "lx60.fpga", 0x10000);
-    memory_region_add_subregion(address_space, base, &s->iomem);
+    memory_region_add_subregion(address_space, base, &s->iomem, &error_abort);
     lx60_fpga_reset(s);
     qemu_register_reset(lx60_fpga_reset, s);
     return s;
@@ -138,14 +138,14 @@ static void lx60_net_init(MemoryRegion *address_space,
     s = SYS_BUS_DEVICE(dev);
     sysbus_connect_irq(s, 0, irq);
     memory_region_add_subregion(address_space, base,
-            sysbus_mmio_get_region(s, 0));
+            sysbus_mmio_get_region(s, 0), &error_abort);
     memory_region_add_subregion(address_space, descriptors,
-            sysbus_mmio_get_region(s, 1));
+            sysbus_mmio_get_region(s, 1), &error_abort);
 
     ram = g_malloc(sizeof(*ram));
     memory_region_init_ram(ram, OBJECT(s), "open_eth.ram", 16384, &error_abort);
     vmstate_register_ram_global(ram);
-    memory_region_add_subregion(address_space, buffers, ram);
+    memory_region_add_subregion(address_space, buffers, ram, &error_abort);
 }
 
 static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
@@ -225,12 +225,13 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
     memory_region_init_ram(ram, NULL, "lx60.dram", machine->ram_size,
                            &error_abort);
     vmstate_register_ram_global(ram);
-    memory_region_add_subregion(system_memory, 0, ram);
+    memory_region_add_subregion(system_memory, 0, ram, &error_abort);
 
     system_io = g_malloc(sizeof(*system_io));
     memory_region_init_io(system_io, NULL, &lx60_io_ops, NULL, "lx60.io",
                           224 * 1024 * 1024);
-    memory_region_add_subregion(system_memory, 0xf0000000, system_io);
+    memory_region_add_subregion(system_memory, 0xf0000000, system_io,
+                                &error_abort);
     lx60_fpga_init(system_io, 0x0d020000);
     if (nd_table[0].used) {
         lx60_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000,
@@ -277,7 +278,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
         memory_region_init_ram(rom, NULL, "lx60.sram", board->sram_size,
                                &error_abort);
         vmstate_register_ram_global(rom);
-        memory_region_add_subregion(system_memory, 0xfe000000, rom);
+        memory_region_add_subregion(system_memory, 0xfe000000, rom,
+                                    &error_abort);
 
         if (kernel_cmdline) {
             bp_size += get_tag_size(strlen(kernel_cmdline) + 1);
@@ -377,7 +379,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
                     board->flash_size - board->flash_boot_base < 0x02000000 ?
                     board->flash_size - board->flash_boot_base : 0x02000000);
             memory_region_add_subregion(system_memory, 0xfe000000,
-                    flash_io);
+                    flash_io, &error_abort);
         }
     }
 }
diff --git a/include/exec/memory.h b/include/exec/memory.h
index b9e6112..ce0320a 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -928,7 +928,8 @@ void memory_region_del_eventfd(MemoryRegion *mr,
  */
 void memory_region_add_subregion(MemoryRegion *mr,
                                  hwaddr offset,
-                                 MemoryRegion *subregion);
+                                 MemoryRegion *subregion,
+                                 Error **errp);
 /**
  * memory_region_add_subregion_overlap: Add a subregion to a container
  *                                      with overlap.
diff --git a/ioport.c b/ioport.c
index e39093e..8943e16 100644
--- a/ioport.c
+++ b/ioport.c
@@ -257,7 +257,7 @@ static void portio_list_add_1(PortioList *piolist,
         memory_region_set_flush_coalesced(&mrpio->mr);
     }
     memory_region_add_subregion(piolist->address_space,
-                                start + off_low, &mrpio->mr);
+                                start + off_low, &mrpio->mr, &error_abort);
     piolist->regions[piolist->nr] = &mrpio->mr;
     ++piolist->nr;
 }
diff --git a/memory.c b/memory.c
index 4558d85..360a5b8 100644
--- a/memory.c
+++ b/memory.c
@@ -1763,7 +1763,8 @@ done:
 
 static void memory_region_add_subregion_common(MemoryRegion *mr,
                                                hwaddr offset,
-                                               MemoryRegion *subregion)
+                                               MemoryRegion *subregion,
+                                               Error **errp)
 {
     assert(!subregion->container);
     subregion->container = mr;
@@ -1781,11 +1782,11 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
 
 void memory_region_add_subregion(MemoryRegion *mr,
                                  hwaddr offset,
-                                 MemoryRegion *subregion)
+                                 MemoryRegion *subregion, Error **errp)
 {
     subregion->may_overlap = false;
     subregion->priority = 0;
-    memory_region_add_subregion_common(mr, offset, subregion);
+    memory_region_add_subregion_common(mr, offset, subregion, errp);
 }
 
 void memory_region_add_subregion_overlap(MemoryRegion *mr,
@@ -1795,7 +1796,7 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
 {
     subregion->may_overlap = true;
     subregion->priority = priority;
-    memory_region_add_subregion_common(mr, offset, subregion);
+    memory_region_add_subregion_common(mr, offset, subregion, &error_abort);
 }
 
 void memory_region_del_subregion(MemoryRegion *mr,
diff --git a/numa.c b/numa.c
index 3c80059..0ec9e58 100644
--- a/numa.c
+++ b/numa.c
@@ -469,7 +469,7 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
             exit(1);
         }
 
-        memory_region_add_subregion(mr, addr, seg);
+        memory_region_add_subregion(mr, addr, seg, &error_abort);
         vmstate_register_ram_global(seg);
         addr += size;
     }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [RFC v3 8/8] memory: add support for deleting HVA mapped MemoryRegion
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
                   ` (6 preceding siblings ...)
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting Igor Mammedov
@ 2015-07-08  9:46 ` Igor Mammedov
  2015-07-08  9:58   ` Michael S. Tsirkin
  2015-07-08 10:01 ` [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Michael S. Tsirkin
  8 siblings, 1 reply; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, mst

Although memory_region_del_subregion() removes MemoryRegion
from current address space, it's possible that it's still
in use/referenced until old address space view is destroyed.
That doesn't allow to unmap it from HVA region at the time
of memory_region_del_subregion().
As a solution track HVA mapped MemoryRegions in a list and
don't allow to map another MemoryRegion at the same address
until respective MemoryRegion is destroyed, delaying unmapping
from HVA range to the time MemoryRegion destructor is called.

In memory hotplug terms it would mean that user should delete
corresponding backend along with pc-dimm device:
 device_del dimm1
 object_del dimm1_backend_memdev
after that dimm1_backend_memdev's MemoryRegion will be destroyed
once all accesses to it are gone and old flatview is destroyed as
well.
As result it's possible that a following "device_add pc-dimm" at
the same address may fail due to old mapping is still being present,
hence add error argument to memory_region_add_subregion() API
so it could report error and hotplug could be cancelled gracefully.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/mem/pc-dimm.c      |  6 +++++-
 include/exec/memory.h |  2 ++
 memory.c              | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 8cc9118..d17c22f 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -95,7 +95,11 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
         goto out;
     }
 
-    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr, &error_abort);
+    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr, &local_err);
+    if (local_err) {
+        goto out;
+    }
+
     vmstate_register_ram(mr, dev);
     numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
 
diff --git a/include/exec/memory.h b/include/exec/memory.h
index ce0320a..d9c53f9 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -174,6 +174,7 @@ struct MemoryRegion {
     bool romd_mode;
     bool ram;
     void *rsvd_hva;
+    bool hva_mapped;
     bool skip_dump;
     bool readonly; /* For RAM regions */
     bool enabled;
@@ -188,6 +189,7 @@ struct MemoryRegion {
     QTAILQ_HEAD(subregions, MemoryRegion) subregions;
     QTAILQ_ENTRY(MemoryRegion) subregions_link;
     QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
+    QTAILQ_ENTRY(MemoryRegion) hva_link;
     const char *name;
     uint8_t dirty_log_mask;
     unsigned ioeventfd_nb;
diff --git a/memory.c b/memory.c
index 360a5b8..e3c1b36 100644
--- a/memory.c
+++ b/memory.c
@@ -34,6 +34,7 @@ static unsigned memory_region_transaction_depth;
 static bool memory_region_update_pending;
 static bool ioeventfd_update_pending;
 static bool global_dirty_log = false;
+static QemuMutex hva_lock;
 
 static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
     = QTAILQ_HEAD_INITIALIZER(memory_listeners);
@@ -1761,6 +1762,24 @@ done:
     memory_region_transaction_commit();
 }
 
+static QTAILQ_HEAD(, MemoryRegion) hva_mapped_head =
+    QTAILQ_HEAD_INITIALIZER(hva_mapped_head);
+
+static void memory_region_destructor_hva_ram(MemoryRegion *mr)
+{
+    MemoryRegion *h, *tmp;
+
+    qemu_mutex_lock(&hva_lock);
+    qemu_ram_unmap_hva(mr->ram_addr);
+    memory_region_destructor_ram(mr);
+    QTAILQ_FOREACH_SAFE(h, &hva_mapped_head, hva_link, tmp) {
+        if (mr == h) {
+            QTAILQ_REMOVE(&hva_mapped_head, h, hva_link);
+        }
+    }
+    qemu_mutex_unlock(&hva_lock);
+}
+
 static void memory_region_add_subregion_common(MemoryRegion *mr,
                                                hwaddr offset,
                                                MemoryRegion *subregion,
@@ -1772,8 +1791,43 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
 
     if (subregion->ram) {
         if (mr->rsvd_hva) {
+            MemoryRegion *h, *tmp;
+            Int128 e, oe;
+
+            assert(!subregion->hva_mapped);
+            qemu_mutex_lock(&hva_lock);
+
+            QTAILQ_FOREACH_SAFE(h, &hva_mapped_head, hva_link, tmp) {
+                if (subregion == h) {
+                    error_setg(errp, "HVA mapped memory region '%s' is not "
+                               "reusable, use a new one instead",
+                               subregion->name);
+                    qemu_mutex_unlock(&hva_lock);
+                    return;
+                }
+
+                e = int128_add(int128_make64(h->addr),
+                               int128_make64(memory_region_size(h)));
+                oe = int128_add(int128_make64(offset),
+                                int128_make64(memory_region_size(subregion)));
+                if (offset >= h->addr && int128_le(oe, e)) {
+                    MemoryRegionSection rsvd_hva;
+                    rsvd_hva = memory_region_find_hva_range(mr);
+                    error_setg(errp, "memory at 0x%" PRIx64 " is still in use"
+                               "by HVA mapped region: %s",
+                               rsvd_hva.offset_within_address_space + offset,
+                               h->name);
+                    qemu_mutex_unlock(&hva_lock);
+                    return;
+                }
+            }
+
+            QTAILQ_INSERT_TAIL(&hva_mapped_head, subregion, hva_link);
+            subregion->destructor = memory_region_destructor_hva_ram;
+            subregion->hva_mapped = true;
             qemu_ram_remap_hva(subregion->ram_addr,
                 memory_region_get_ram_ptr(mr) + subregion->addr);
+            qemu_mutex_unlock(&hva_lock);
         }
     }
 
@@ -2288,6 +2342,7 @@ static const TypeInfo memory_region_info = {
 static void memory_register_types(void)
 {
     type_register_static(&memory_region_info);
+    qemu_mutex_init(&hva_lock);
 }
 
 type_init(memory_register_types)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 8/8] memory: add support for deleting HVA mapped MemoryRegion
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 8/8] memory: add support for deleting HVA mapped MemoryRegion Igor Mammedov
@ 2015-07-08  9:58   ` Michael S. Tsirkin
  2015-07-08 14:43     ` Igor Mammedov
  0 siblings, 1 reply; 31+ messages in thread
From: Michael S. Tsirkin @ 2015-07-08  9:58 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, qemu-devel

On Wed, Jul 08, 2015 at 11:46:48AM +0200, Igor Mammedov wrote:
> Although memory_region_del_subregion() removes MemoryRegion
> from current address space, it's possible that it's still
> in use/referenced until old address space view is destroyed.
> That doesn't allow to unmap it from HVA region at the time
> of memory_region_del_subregion().
> As a solution track HVA mapped MemoryRegions in a list and
> don't allow to map another MemoryRegion at the same address
> until respective MemoryRegion is destroyed, delaying unmapping
> from HVA range to the time MemoryRegion destructor is called.
> 
> In memory hotplug terms it would mean that user should delete
> corresponding backend along with pc-dimm device:
>  device_del dimm1
>  object_del dimm1_backend_memdev
> after that dimm1_backend_memdev's MemoryRegion will be destroyed
> once all accesses to it are gone and old flatview is destroyed as
> well.
> As result it's possible that a following "device_add pc-dimm" at
> the same address may fail due to old mapping is still being present,


s/is still/still/

> hence add error argument to memory_region_add_subregion() API
> so it could report error and hotplug could be cancelled gracefully.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

The commit log seems a bit confusing.
API was added in previous patch, and this one actually
uses it.

> ---
>  hw/mem/pc-dimm.c      |  6 +++++-
>  include/exec/memory.h |  2 ++
>  memory.c              | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 62 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
> index 8cc9118..d17c22f 100644
> --- a/hw/mem/pc-dimm.c
> +++ b/hw/mem/pc-dimm.c
> @@ -95,7 +95,11 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
>          goto out;
>      }
>  
> -    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr, &error_abort);
> +    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr, &local_err);
> +    if (local_err) {
> +        goto out;
> +    }
> +
>      vmstate_register_ram(mr, dev);
>      numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
>  
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index ce0320a..d9c53f9 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -174,6 +174,7 @@ struct MemoryRegion {
>      bool romd_mode;
>      bool ram;
>      void *rsvd_hva;
> +    bool hva_mapped;
>      bool skip_dump;
>      bool readonly; /* For RAM regions */
>      bool enabled;
> @@ -188,6 +189,7 @@ struct MemoryRegion {
>      QTAILQ_HEAD(subregions, MemoryRegion) subregions;
>      QTAILQ_ENTRY(MemoryRegion) subregions_link;
>      QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
> +    QTAILQ_ENTRY(MemoryRegion) hva_link;
>      const char *name;
>      uint8_t dirty_log_mask;
>      unsigned ioeventfd_nb;
> diff --git a/memory.c b/memory.c
> index 360a5b8..e3c1b36 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -34,6 +34,7 @@ static unsigned memory_region_transaction_depth;
>  static bool memory_region_update_pending;
>  static bool ioeventfd_update_pending;
>  static bool global_dirty_log = false;
> +static QemuMutex hva_lock;
>  
>  static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
>      = QTAILQ_HEAD_INITIALIZER(memory_listeners);
> @@ -1761,6 +1762,24 @@ done:
>      memory_region_transaction_commit();
>  }
>  
> +static QTAILQ_HEAD(, MemoryRegion) hva_mapped_head =
> +    QTAILQ_HEAD_INITIALIZER(hva_mapped_head);
> +
> +static void memory_region_destructor_hva_ram(MemoryRegion *mr)
> +{
> +    MemoryRegion *h, *tmp;
> +
> +    qemu_mutex_lock(&hva_lock);
> +    qemu_ram_unmap_hva(mr->ram_addr);
> +    memory_region_destructor_ram(mr);
> +    QTAILQ_FOREACH_SAFE(h, &hva_mapped_head, hva_link, tmp) {
> +        if (mr == h) {
> +            QTAILQ_REMOVE(&hva_mapped_head, h, hva_link);
> +        }
> +    }
> +    qemu_mutex_unlock(&hva_lock);
> +}
> +
>  static void memory_region_add_subregion_common(MemoryRegion *mr,
>                                                 hwaddr offset,
>                                                 MemoryRegion *subregion,
> @@ -1772,8 +1791,43 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
>  
>      if (subregion->ram) {
>          if (mr->rsvd_hva) {
> +            MemoryRegion *h, *tmp;
> +            Int128 e, oe;
> +
> +            assert(!subregion->hva_mapped);
> +            qemu_mutex_lock(&hva_lock);
> +
> +            QTAILQ_FOREACH_SAFE(h, &hva_mapped_head, hva_link, tmp) {
> +                if (subregion == h) {
> +                    error_setg(errp, "HVA mapped memory region '%s' is not "
> +                               "reusable, use a new one instead",
> +                               subregion->name);
> +                    qemu_mutex_unlock(&hva_lock);
> +                    return;
> +                }
> +
> +                e = int128_add(int128_make64(h->addr),
> +                               int128_make64(memory_region_size(h)));
> +                oe = int128_add(int128_make64(offset),
> +                                int128_make64(memory_region_size(subregion)));
> +                if (offset >= h->addr && int128_le(oe, e)) {
> +                    MemoryRegionSection rsvd_hva;
> +                    rsvd_hva = memory_region_find_hva_range(mr);
> +                    error_setg(errp, "memory at 0x%" PRIx64 " is still in use"
> +                               "by HVA mapped region: %s",
> +                               rsvd_hva.offset_within_address_space + offset,
> +                               h->name);
> +                    qemu_mutex_unlock(&hva_lock);
> +                    return;
> +                }
> +            }
> +
> +            QTAILQ_INSERT_TAIL(&hva_mapped_head, subregion, hva_link);
> +            subregion->destructor = memory_region_destructor_hva_ram;
> +            subregion->hva_mapped = true;
>              qemu_ram_remap_hva(subregion->ram_addr,
>                  memory_region_get_ram_ptr(mr) + subregion->addr);
> +            qemu_mutex_unlock(&hva_lock);
>          }
>      }
>  
> @@ -2288,6 +2342,7 @@ static const TypeInfo memory_region_info = {
>  static void memory_register_types(void)
>  {
>      type_register_static(&memory_region_info);
> +    qemu_mutex_init(&hva_lock);
>  }
>  
>  type_init(memory_register_types)
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
                   ` (7 preceding siblings ...)
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 8/8] memory: add support for deleting HVA mapped MemoryRegion Igor Mammedov
@ 2015-07-08 10:01 ` Michael S. Tsirkin
  2015-07-08 11:41   ` Igor Mammedov
  2015-07-08 15:46   ` Igor Mammedov
  8 siblings, 2 replies; 31+ messages in thread
From: Michael S. Tsirkin @ 2015-07-08 10:01 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, qemu-devel

On Wed, Jul 08, 2015 at 11:46:40AM +0200, Igor Mammedov wrote:
> Changelog:
>  v2->v3:
>    * fixed(work-arouned) unmapping issues,
>      now memory subsytem keeps track of HVA mapped
>      regions and doesn't allow to map a new region
>      at address where previos has benn mapped until
>      previous region is gone
>    * fixed offset calculations in memory_region_find_hva_range()
>      in 2/8
>    * redone MemorySection folding into HVA range for VHOST,
>      now compacted memory map is temporary and passed only to vhost
>      backend and doesn't touch original memory map used by QEMU
>  v1->v2:
>    * take into account Paolo's review comments
>      * do not overload ram_addr
>      * ifdef linux specific code
>    * reseve HVA using API from exec.c instead of calling
>      mmap() dircely from memory.c
>    * support unmapping of HVA remapped region
> 
> When more than ~50 pc-dimm devices are hotplugged with
> vhost enabled, QEMU will assert in vhost vhost_commit()
> due to backend refusing to accept too many memory ranges.
> 
> Series introduces Reserved HVA MemoryRegion container
> where to all hotplugged memory is remapped and passes
> the single container range to vhost instead of multiple
> memory ranges for each hotlugged pc-dimm device.

Did not review yet, two procedural comments:

- this fixes qemu on current kernels, so it's a bugfix

- this changes the semantics of memory hot unplug slightly
  so I think it's important to merge in 2.4 before we
  release qemu with memory hot unplug, this way we
  won't have to maintain old semantics forever


> It's an alternative approach to increasing backend supported
> memory regions limit. 
> 
> git branch for testing:
>   https://github.com/imammedo/qemu/commits/vhost_one_hp_range_v3
> 
> Igor Mammedov (8):
>   memory: get rid of memory_region_destructor_ram_from_ptr()
>   memory: introduce MemoryRegion container with reserved HVA range
>   pc: reserve hotpluggable memory range with
>     memory_region_init_hva_range()
>   pc: fix QEMU crashing when more than ~50 memory hotplugged
>   exec: make sure that RAMBlock descriptor won't be leaked
>   exec: add qemu_ram_unmap_hva() API for unmapping memory from HVA area
>   memory: extend memory_region_add_subregion() to support error
>     reporting
>   memory: add support for deleting HVA mapped MemoryRegion
> 
>  exec.c                                   |  71 ++++++++++++-------
>  hw/acpi/core.c                           |   6 +-
>  hw/acpi/cpu_hotplug.c                    |   2 +-
>  hw/acpi/ich9.c                           |   8 ++-
>  hw/acpi/memory_hotplug.c                 |   3 +-
>  hw/acpi/pcihp.c                          |   3 +-
>  hw/acpi/piix4.c                          |   6 +-
>  hw/alpha/typhoon.c                       |  16 ++---
>  hw/arm/armv7m.c                          |   2 +-
>  hw/arm/cubieboard.c                      |   2 +-
>  hw/arm/digic_boards.c                    |   2 +-
>  hw/arm/exynos4210.c                      |  12 ++--
>  hw/arm/highbank.c                        |   4 +-
>  hw/arm/integratorcp.c                    |   5 +-
>  hw/arm/kzm.c                             |   9 ++-
>  hw/arm/mainstone.c                       |   2 +-
>  hw/arm/musicpal.c                        |   5 +-
>  hw/arm/omap1.c                           |  59 +++++++++-------
>  hw/arm/omap2.c                           |   8 ++-
>  hw/arm/omap_sx1.c                        |  19 +++--
>  hw/arm/palm.c                            |  14 ++--
>  hw/arm/pxa2xx.c                          |  30 +++++---
>  hw/arm/realview.c                        |   8 +--
>  hw/arm/spitz.c                           |   2 +-
>  hw/arm/stellaris.c                       |   7 +-
>  hw/arm/stm32f205_soc.c                   |   8 ++-
>  hw/arm/strongarm.c                       |   2 +-
>  hw/arm/tosa.c                            |   2 +-
>  hw/arm/versatilepb.c                     |   2 +-
>  hw/arm/vexpress.c                        |  15 ++--
>  hw/arm/virt.c                            |  12 ++--
>  hw/arm/xilinx_zynq.c                     |   5 +-
>  hw/arm/xlnx-ep108.c                      |   3 +-
>  hw/arm/xlnx-zynqmp.c                     |   3 +-
>  hw/block/onenand.c                       |   2 +-
>  hw/block/pflash_cfi02.c                  |   3 +-
>  hw/char/debugcon.c                       |   2 +-
>  hw/char/mcf_uart.c                       |   2 +-
>  hw/char/omap_uart.c                      |   2 +-
>  hw/char/parallel.c                       |   2 +-
>  hw/char/serial-pci.c                     |   2 +-
>  hw/char/serial.c                         |   4 +-
>  hw/char/sh_serial.c                      |   6 +-
>  hw/core/platform-bus.c                   |   2 +-
>  hw/core/sysbus.c                         |   4 +-
>  hw/cpu/a15mpcore.c                       |   6 +-
>  hw/cpu/a9mpcore.c                        |  18 +++--
>  hw/cpu/arm11mpcore.c                     |  15 ++--
>  hw/cris/axis_dev88.c                     |  10 +--
>  hw/display/cirrus_vga.c                  |  11 +--
>  hw/display/omap_dss.c                    |   2 +-
>  hw/display/omap_lcdc.c                   |   2 +-
>  hw/display/pxa2xx_lcd.c                  |   2 +-
>  hw/display/sm501.c                       |   9 +--
>  hw/display/tc6393xb.c                    |   5 +-
>  hw/display/vga-isa-mm.c                  |   6 +-
>  hw/display/vga-pci.c                     |   6 +-
>  hw/display/vga.c                         |   3 +-
>  hw/dma/etraxfs_dma.c                     |   3 +-
>  hw/dma/i8257.c                           |   5 +-
>  hw/dma/omap_dma.c                        |   4 +-
>  hw/dma/rc4030.c                          |   4 +-
>  hw/i386/kvm/pci-assign.c                 |   6 +-
>  hw/i386/pc.c                             |  16 +++--
>  hw/i386/pc_sysfw.c                       |   2 +-
>  hw/ide/cmd646.c                          |   6 +-
>  hw/ide/piix.c                            |   6 +-
>  hw/ide/via.c                             |   6 +-
>  hw/input/pxa2xx_keypad.c                 |   2 +-
>  hw/intc/apic_common.c                    |   3 +-
>  hw/intc/armv7m_nvic.c                    |   5 +-
>  hw/intc/exynos4210_gic.c                 |   6 +-
>  hw/intc/openpic.c                        |   2 +-
>  hw/intc/realview_gic.c                   |   6 +-
>  hw/intc/sh_intc.c                        |   6 +-
>  hw/isa/apm.c                             |   2 +-
>  hw/isa/isa-bus.c                         |   3 +-
>  hw/isa/vt82c686.c                        |   7 +-
>  hw/lm32/lm32_boards.c                    |   6 +-
>  hw/lm32/milkymist.c                      |   3 +-
>  hw/m68k/an5206.c                         |   5 +-
>  hw/m68k/dummy_m68k.c                     |   2 +-
>  hw/m68k/mcf5206.c                        |   2 +-
>  hw/m68k/mcf5208.c                        |  10 +--
>  hw/m68k/mcf_intc.c                       |   2 +-
>  hw/mem/pc-dimm.c                         |   6 +-
>  hw/microblaze/petalogix_ml605_mmu.c      |   6 +-
>  hw/microblaze/petalogix_s3adsp1800_mmu.c |   5 +-
>  hw/mips/gt64xxx_pci.c                    |   9 +--
>  hw/mips/mips_fulong2e.c                  |   5 +-
>  hw/mips/mips_jazz.c                      |  30 +++++---
>  hw/mips/mips_malta.c                     |  17 +++--
>  hw/mips/mips_mipssim.c                   |  11 +--
>  hw/mips/mips_r4k.c                       |  14 ++--
>  hw/misc/debugexit.c                      |   2 +-
>  hw/misc/ivshmem.c                        |   4 +-
>  hw/misc/macio/macio.c                    |  24 ++++---
>  hw/misc/omap_gpmc.c                      |   7 +-
>  hw/misc/omap_l4.c                        |   3 +-
>  hw/misc/omap_sdrc.c                      |   2 +-
>  hw/misc/pc-testdev.c                     |  11 +--
>  hw/moxie/moxiesim.c                      |   4 +-
>  hw/net/fsl_etsec/etsec.c                 |   3 +-
>  hw/net/mcf_fec.c                         |   2 +-
>  hw/openrisc/openrisc_sim.c               |   6 +-
>  hw/pci-host/apb.c                        |   3 +-
>  hw/pci-host/grackle.c                    |   2 +-
>  hw/pci-host/piix.c                       |   3 +-
>  hw/pci-host/ppce500.c                    |  13 ++--
>  hw/pci-host/prep.c                       |  24 ++++---
>  hw/pci-host/q35.c                        |   8 ++-
>  hw/pci-host/uninorth.c                   |   4 +-
>  hw/pci/msix.c                            |   6 +-
>  hw/pci/pcie_host.c                       |   3 +-
>  hw/pci/shpc.c                            |   2 +-
>  hw/pcmcia/pxa2xx.c                       |   6 +-
>  hw/ppc/e500.c                            |  14 ++--
>  hw/ppc/mac_newworld.c                    |  14 ++--
>  hw/ppc/mac_oldworld.c                    |   6 +-
>  hw/ppc/ppc405_boards.c                   |  12 ++--
>  hw/ppc/ppc405_uc.c                       |  16 +++--
>  hw/ppc/ppc440_bamboo.c                   |   3 +-
>  hw/ppc/ppc4xx_devs.c                     |   4 +-
>  hw/ppc/ppc4xx_pci.c                      |   9 ++-
>  hw/ppc/prep.c                            |   4 +-
>  hw/ppc/spapr.c                           |   4 +-
>  hw/ppc/spapr_pci.c                       |   8 +--
>  hw/ppc/spapr_pci_vfio.c                  |   2 +-
>  hw/ppc/virtex_ml507.c                    |   3 +-
>  hw/s390x/s390-virtio-ccw.c               |   2 +-
>  hw/s390x/s390-virtio.c                   |   2 +-
>  hw/s390x/sclp.c                          |   3 +-
>  hw/sd/omap_mmc.c                         |   2 +-
>  hw/sd/pxa2xx_mmci.c                      |   2 +-
>  hw/sh4/r2d.c                             |   5 +-
>  hw/sh4/sh7750.c                          |  21 ++++--
>  hw/sh4/sh_pci.c                          |   6 +-
>  hw/sh4/shix.c                            |   6 +-
>  hw/sparc/leon3.c                         |   6 +-
>  hw/sparc64/sun4u.c                       |   2 +-
>  hw/timer/m48t59.c                        |   3 +-
>  hw/timer/sh_timer.c                      |   6 +-
>  hw/tpm/tpm_tis.c                         |   2 +-
>  hw/tricore/tricore_testboard.c           |  12 ++--
>  hw/unicore32/puv3.c                      |   6 +-
>  hw/usb/hcd-ehci-sysbus.c                 |   2 +-
>  hw/usb/hcd-ehci.c                        |   8 ++-
>  hw/usb/hcd-xhci.c                        |  15 ++--
>  hw/vfio/common.c                         |   2 +-
>  hw/vfio/pci.c                            |   6 +-
>  hw/virtio/vhost.c                        |  47 +++++++++++-
>  hw/virtio/virtio-pci.c                   |   3 +-
>  hw/xtensa/sim.c                          |   5 +-
>  hw/xtensa/xtfpga.c                       |  18 ++---
>  include/exec/cpu-common.h                |   3 +
>  include/exec/memory.h                    |  49 ++++++++++++-
>  include/exec/ram_addr.h                  |   1 -
>  include/hw/virtio/vhost.h                |   1 +
>  ioport.c                                 |   2 +-
>  memory.c                                 | 118 ++++++++++++++++++++++++++++---
>  numa.c                                   |   2 +-
>  161 files changed, 867 insertions(+), 458 deletions(-)
> 
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting Igor Mammedov
@ 2015-07-08 11:03   ` Michael S. Tsirkin
  2015-07-08 11:09   ` Peter Maydell
  1 sibling, 0 replies; 31+ messages in thread
From: Michael S. Tsirkin @ 2015-07-08 11:03 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, qemu-devel

On Wed, Jul 08, 2015 at 11:46:47AM +0200, Igor Mammedov wrote:
> extends memory_region_add_subregion() by adding Error**
> argument to allow t fail and return a error from it.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

_overlap needs same treatment too for completeness.
Can be a separate patch.

> ---
>  hw/acpi/core.c                           |  6 ++--
>  hw/acpi/cpu_hotplug.c                    |  2 +-
>  hw/acpi/ich9.c                           |  8 +++--
>  hw/acpi/memory_hotplug.c                 |  3 +-
>  hw/acpi/pcihp.c                          |  3 +-
>  hw/acpi/piix4.c                          |  6 ++--
>  hw/alpha/typhoon.c                       | 16 ++++-----
>  hw/arm/armv7m.c                          |  2 +-
>  hw/arm/cubieboard.c                      |  2 +-
>  hw/arm/digic_boards.c                    |  2 +-
>  hw/arm/exynos4210.c                      | 12 +++----
>  hw/arm/highbank.c                        |  4 +--
>  hw/arm/integratorcp.c                    |  5 +--
>  hw/arm/kzm.c                             |  9 +++--
>  hw/arm/mainstone.c                       |  2 +-
>  hw/arm/musicpal.c                        |  5 +--
>  hw/arm/omap1.c                           | 59 ++++++++++++++++++--------------
>  hw/arm/omap2.c                           |  8 +++--
>  hw/arm/omap_sx1.c                        | 19 ++++++----
>  hw/arm/palm.c                            | 14 +++++---
>  hw/arm/pxa2xx.c                          | 30 ++++++++++------
>  hw/arm/realview.c                        |  8 ++---
>  hw/arm/spitz.c                           |  2 +-
>  hw/arm/stellaris.c                       |  7 ++--
>  hw/arm/stm32f205_soc.c                   |  8 +++--
>  hw/arm/strongarm.c                       |  2 +-
>  hw/arm/tosa.c                            |  2 +-
>  hw/arm/versatilepb.c                     |  2 +-
>  hw/arm/vexpress.c                        | 15 ++++----
>  hw/arm/virt.c                            | 12 ++++---
>  hw/arm/xilinx_zynq.c                     |  5 +--
>  hw/arm/xlnx-ep108.c                      |  3 +-
>  hw/arm/xlnx-zynqmp.c                     |  3 +-
>  hw/block/onenand.c                       |  2 +-
>  hw/block/pflash_cfi02.c                  |  3 +-
>  hw/char/debugcon.c                       |  2 +-
>  hw/char/mcf_uart.c                       |  2 +-
>  hw/char/omap_uart.c                      |  2 +-
>  hw/char/parallel.c                       |  2 +-
>  hw/char/serial-pci.c                     |  2 +-
>  hw/char/serial.c                         |  4 +--
>  hw/char/sh_serial.c                      |  6 ++--
>  hw/core/platform-bus.c                   |  2 +-
>  hw/core/sysbus.c                         |  4 +--
>  hw/cpu/a15mpcore.c                       |  6 ++--
>  hw/cpu/a9mpcore.c                        | 18 ++++++----
>  hw/cpu/arm11mpcore.c                     | 15 +++++---
>  hw/cris/axis_dev88.c                     | 10 +++---
>  hw/display/cirrus_vga.c                  | 11 +++---
>  hw/display/omap_dss.c                    |  2 +-
>  hw/display/omap_lcdc.c                   |  2 +-
>  hw/display/pxa2xx_lcd.c                  |  2 +-
>  hw/display/sm501.c                       |  9 ++---
>  hw/display/tc6393xb.c                    |  5 +--
>  hw/display/vga-isa-mm.c                  |  6 ++--
>  hw/display/vga-pci.c                     |  6 ++--
>  hw/display/vga.c                         |  3 +-
>  hw/dma/etraxfs_dma.c                     |  3 +-
>  hw/dma/i8257.c                           |  5 +--
>  hw/dma/omap_dma.c                        |  4 +--
>  hw/dma/rc4030.c                          |  4 +--
>  hw/i386/kvm/pci-assign.c                 |  6 ++--
>  hw/i386/pc.c                             | 12 ++++---
>  hw/i386/pc_sysfw.c                       |  2 +-
>  hw/ide/cmd646.c                          |  6 ++--
>  hw/ide/piix.c                            |  6 ++--
>  hw/ide/via.c                             |  6 ++--
>  hw/input/pxa2xx_keypad.c                 |  2 +-
>  hw/intc/apic_common.c                    |  3 +-
>  hw/intc/armv7m_nvic.c                    |  5 +--
>  hw/intc/exynos4210_gic.c                 |  6 ++--
>  hw/intc/openpic.c                        |  2 +-
>  hw/intc/realview_gic.c                   |  6 ++--
>  hw/intc/sh_intc.c                        |  6 ++--
>  hw/isa/apm.c                             |  2 +-
>  hw/isa/isa-bus.c                         |  3 +-
>  hw/isa/vt82c686.c                        |  7 ++--
>  hw/lm32/lm32_boards.c                    |  6 ++--
>  hw/lm32/milkymist.c                      |  3 +-
>  hw/m68k/an5206.c                         |  5 +--
>  hw/m68k/dummy_m68k.c                     |  2 +-
>  hw/m68k/mcf5206.c                        |  2 +-
>  hw/m68k/mcf5208.c                        | 10 +++---
>  hw/m68k/mcf_intc.c                       |  2 +-
>  hw/mem/pc-dimm.c                         |  2 +-
>  hw/microblaze/petalogix_ml605_mmu.c      |  6 ++--
>  hw/microblaze/petalogix_s3adsp1800_mmu.c |  5 +--
>  hw/mips/gt64xxx_pci.c                    |  9 ++---
>  hw/mips/mips_fulong2e.c                  |  5 +--
>  hw/mips/mips_jazz.c                      | 30 ++++++++++------
>  hw/mips/mips_malta.c                     | 17 +++++----
>  hw/mips/mips_mipssim.c                   | 11 +++---
>  hw/mips/mips_r4k.c                       | 14 +++++---
>  hw/misc/debugexit.c                      |  2 +-
>  hw/misc/ivshmem.c                        |  4 +--
>  hw/misc/macio/macio.c                    | 24 +++++++------
>  hw/misc/omap_gpmc.c                      |  7 ++--
>  hw/misc/omap_l4.c                        |  3 +-
>  hw/misc/omap_sdrc.c                      |  2 +-
>  hw/misc/pc-testdev.c                     | 11 +++---
>  hw/moxie/moxiesim.c                      |  4 +--
>  hw/net/fsl_etsec/etsec.c                 |  3 +-
>  hw/net/mcf_fec.c                         |  2 +-
>  hw/openrisc/openrisc_sim.c               |  6 ++--
>  hw/pci-host/apb.c                        |  3 +-
>  hw/pci-host/grackle.c                    |  2 +-
>  hw/pci-host/piix.c                       |  3 +-
>  hw/pci-host/ppce500.c                    | 13 ++++---
>  hw/pci-host/prep.c                       | 24 ++++++++-----
>  hw/pci-host/q35.c                        |  8 +++--
>  hw/pci-host/uninorth.c                   |  4 +--
>  hw/pci/msix.c                            |  6 ++--
>  hw/pci/pcie_host.c                       |  3 +-
>  hw/pci/shpc.c                            |  2 +-
>  hw/pcmcia/pxa2xx.c                       |  6 ++--
>  hw/ppc/e500.c                            | 14 ++++----
>  hw/ppc/mac_newworld.c                    | 14 +++++---
>  hw/ppc/mac_oldworld.c                    |  6 ++--
>  hw/ppc/ppc405_boards.c                   | 12 ++++---
>  hw/ppc/ppc405_uc.c                       | 16 +++++----
>  hw/ppc/ppc440_bamboo.c                   |  3 +-
>  hw/ppc/ppc4xx_devs.c                     |  4 +--
>  hw/ppc/ppc4xx_pci.c                      |  9 +++--
>  hw/ppc/prep.c                            |  4 +--
>  hw/ppc/spapr.c                           |  4 +--
>  hw/ppc/spapr_pci.c                       |  8 ++---
>  hw/ppc/spapr_pci_vfio.c                  |  2 +-
>  hw/ppc/virtex_ml507.c                    |  3 +-
>  hw/s390x/s390-virtio-ccw.c               |  2 +-
>  hw/s390x/s390-virtio.c                   |  2 +-
>  hw/s390x/sclp.c                          |  3 +-
>  hw/sd/omap_mmc.c                         |  2 +-
>  hw/sd/pxa2xx_mmci.c                      |  2 +-
>  hw/sh4/r2d.c                             |  5 +--
>  hw/sh4/sh7750.c                          | 21 ++++++++----
>  hw/sh4/sh_pci.c                          |  6 ++--
>  hw/sh4/shix.c                            |  6 ++--
>  hw/sparc/leon3.c                         |  6 ++--
>  hw/sparc64/sun4u.c                       |  2 +-
>  hw/timer/m48t59.c                        |  3 +-
>  hw/timer/sh_timer.c                      |  6 ++--
>  hw/tpm/tpm_tis.c                         |  2 +-
>  hw/tricore/tricore_testboard.c           | 12 +++----
>  hw/unicore32/puv3.c                      |  6 ++--
>  hw/usb/hcd-ehci-sysbus.c                 |  2 +-
>  hw/usb/hcd-ehci.c                        |  8 +++--
>  hw/usb/hcd-xhci.c                        | 15 +++++---
>  hw/vfio/common.c                         |  2 +-
>  hw/vfio/pci.c                            |  6 ++--
>  hw/virtio/virtio-pci.c                   |  3 +-
>  hw/xtensa/sim.c                          |  5 +--
>  hw/xtensa/xtfpga.c                       | 18 +++++-----
>  include/exec/memory.h                    |  3 +-
>  ioport.c                                 |  2 +-
>  memory.c                                 |  9 ++---
>  numa.c                                   |  2 +-
>  156 files changed, 619 insertions(+), 420 deletions(-)
> 
> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index fe6215a..4269240 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -465,7 +465,7 @@ void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
>      ar->pm1.evt.update_sci = update_sci;
>      memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent),
>                            &acpi_pm_evt_ops, ar, "acpi-evt", 4);
> -    memory_region_add_subregion(parent, 0, &ar->pm1.evt.io);
> +    memory_region_add_subregion(parent, 0, &ar->pm1.evt.io, &error_abort);
>  }
>  
>  /* ACPI PM_TMR */
> @@ -529,7 +529,7 @@ void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
>      memory_region_init_io(&ar->tmr.io, memory_region_owner(parent),
>                            &acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
>      memory_region_clear_global_locking(&ar->tmr.io);
> -    memory_region_add_subregion(parent, 8, &ar->tmr.io);
> +    memory_region_add_subregion(parent, 8, &ar->tmr.io, &error_abort);
>  }
>  
>  void acpi_pm_tmr_reset(ACPIREGS *ar)
> @@ -604,7 +604,7 @@ void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
>      qemu_register_wakeup_notifier(&ar->wakeup);
>      memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent),
>                            &acpi_pm_cnt_ops, ar, "acpi-cnt", 2);
> -    memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io);
> +    memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io, &error_abort);
>  
>      fw_cfg = fw_cfg_find();
>      if (fw_cfg) {
> diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
> index f5b9972..7678fec 100644
> --- a/hw/acpi/cpu_hotplug.c
> +++ b/hw/acpi/cpu_hotplug.c
> @@ -72,5 +72,5 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
>      }
>      memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
>                            gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
> -    memory_region_add_subregion(parent, base, &gpe_cpu->io);
> +    memory_region_add_subregion(parent, base, &gpe_cpu->io, &error_abort);
>  }
> diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> index f4dc7a8..daf5a28 100644
> --- a/hw/acpi/ich9.c
> +++ b/hw/acpi/ich9.c
> @@ -215,7 +215,7 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, bool smm_enabled,
>      memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE);
>      memory_region_set_enabled(&pm->io, false);
>      memory_region_add_subregion(pci_address_space_io(lpc_pci),
> -                                0, &pm->io);
> +                                0, &pm->io, &error_abort);
>  
>      acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
>      acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
> @@ -225,11 +225,13 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, bool smm_enabled,
>      acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
>      memory_region_init_io(&pm->io_gpe, OBJECT(lpc_pci), &ich9_gpe_ops, pm,
>                            "acpi-gpe0", ICH9_PMIO_GPE0_LEN);
> -    memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe);
> +    memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe,
> +                                &error_abort);
>  
>      memory_region_init_io(&pm->io_smi, OBJECT(lpc_pci), &ich9_smi_ops, pm,
>                            "acpi-smi", 8);
> -    memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
> +    memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi,
> +                                &error_abort);
>  
>      pm->smm_enabled = smm_enabled;
>      pm->irq = sci_irq;
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index 2ff0d5c..81695cc 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -188,7 +188,8 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
>      state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
>      memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state,
>                            "acpi-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN);
> -    memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io);
> +    memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io,
> +                                &error_abort);
>  }
>  
>  /**
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index fbbc4dd..e1b804a 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -314,7 +314,8 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
>  
>      memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
>                            "acpi-pci-hotplug", s->io_len);
> -    memory_region_add_subregion(address_space_io, s->io_base, &s->io);
> +    memory_region_add_subregion(address_space_io, s->io_base, &s->io,
> +                                &error_abort);
>  
>      object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
>                                     &error_abort);
> diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> index 2cd2fee..634986c 100644
> --- a/hw/acpi/piix4.c
> +++ b/hw/acpi/piix4.c
> @@ -467,12 +467,12 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
>      pm_smbus_init(DEVICE(dev), &s->smb);
>      memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1);
>      memory_region_add_subregion(pci_address_space_io(dev),
> -                                s->smb_io_base, &s->smb.io);
> +                                s->smb_io_base, &s->smb.io, &error_abort);
>  
>      memory_region_init(&s->io, OBJECT(s), "piix4-pm", 64);
>      memory_region_set_enabled(&s->io, false);
>      memory_region_add_subregion(pci_address_space_io(dev),
> -                                0, &s->io);
> +                                0, &s->io, &error_abort);
>  
>      acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
>      acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
> @@ -563,7 +563,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
>  {
>      memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s,
>                            "acpi-gpe0", GPE_LEN);
> -    memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
> +    memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe, &error_abort);
>  
>      acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent,
>                      s->use_acpi_pci_hotplug);
> diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
> index 421162e..4881491 100644
> --- a/hw/alpha/typhoon.c
> +++ b/hw/alpha/typhoon.c
> @@ -847,7 +847,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
>         but the address space hole reserved at this point is 8TB.  */
>      memory_region_allocate_system_memory(&s->ram_region, OBJECT(s), "ram",
>                                           ram_size);
> -    memory_region_add_subregion(addr_space, 0, &s->ram_region);
> +    memory_region_add_subregion(addr_space, 0, &s->ram_region, &error_abort);
>  
>      /* TIGbus, 0x801.0000.0000, 1GB.  */
>      /* ??? The TIGbus is used for delivering interrupts, and access to
> @@ -857,30 +857,30 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
>      memory_region_init_io(&s->pchip.region, OBJECT(s), &pchip_ops, s, "pchip0",
>                            256*MB);
>      memory_region_add_subregion(addr_space, 0x80180000000ULL,
> -                                &s->pchip.region);
> +                                &s->pchip.region, &error_abort);
>  
>      /* Cchip CSRs, 0x801.A000.0000, 256MB.  */
>      memory_region_init_io(&s->cchip.region, OBJECT(s), &cchip_ops, s, "cchip0",
>                            256*MB);
>      memory_region_add_subregion(addr_space, 0x801a0000000ULL,
> -                                &s->cchip.region);
> +                                &s->cchip.region, &error_abort);
>  
>      /* Dchip CSRs, 0x801.B000.0000, 256MB.  */
>      memory_region_init_io(&s->dchip_region, OBJECT(s), &dchip_ops, s, "dchip0",
>                            256*MB);
>      memory_region_add_subregion(addr_space, 0x801b0000000ULL,
> -                                &s->dchip_region);
> +                                &s->dchip_region, &error_abort);
>  
>      /* Pchip0 PCI memory, 0x800.0000.0000, 4GB.  */
>      memory_region_init(&s->pchip.reg_mem, OBJECT(s), "pci0-mem", 4*GB);
>      memory_region_add_subregion(addr_space, 0x80000000000ULL,
> -                                &s->pchip.reg_mem);
> +                                &s->pchip.reg_mem, &error_abort);
>  
>      /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB.  */
>      memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_ignore_ops,
>                            NULL, "pci0-io", 32*MB);
>      memory_region_add_subregion(addr_space, 0x801fc000000ULL,
> -                                &s->pchip.reg_io);
> +                                &s->pchip.reg_io, &error_abort);
>  
>      b = pci_register_bus(dev, "pci",
>                           typhoon_set_irq, sys_map_irq, s,
> @@ -898,13 +898,13 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
>      memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
>                            b, "pci0-iack", 64*MB);
>      memory_region_add_subregion(addr_space, 0x801f8000000ULL,
> -                                &s->pchip.reg_iack);
> +                                &s->pchip.reg_iack, &error_abort);
>  
>      /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB.  */
>      memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops,
>                            b, "pci0-conf", 16*MB);
>      memory_region_add_subregion(addr_space, 0x801fe000000ULL,
> -                                &s->pchip.reg_conf);
> +                                &s->pchip.reg_conf, &error_abort);
>  
>      /* For the record, these are the mappings for the second PCI bus.
>         We can get away with not implementing them because we indicate
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index c6eab6d..e4739fb 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -231,7 +231,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
>         when returning from an exception.  */
>      memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000, &error_abort);
>      vmstate_register_ram_global(hack);
> -    memory_region_add_subregion(system_memory, 0xfffff000, hack);
> +    memory_region_add_subregion(system_memory, 0xfffff000, hack, &error_abort);
>  
>      qemu_register_reset(armv7m_reset, cpu);
>      return pic;
> diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
> index 1582250..d02bdfa 100644
> --- a/hw/arm/cubieboard.c
> +++ b/hw/arm/cubieboard.c
> @@ -66,7 +66,7 @@ static void cubieboard_init(MachineState *machine)
>      memory_region_allocate_system_memory(&s->sdram, NULL, "cubieboard.ram",
>                                           machine->ram_size);
>      memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
> -                                &s->sdram);
> +                                &s->sdram, &error_abort);
>  
>      cubieboard_binfo.ram_size = machine->ram_size;
>      cubieboard_binfo.kernel_filename = machine->kernel_filename;
> diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
> index f8ba9e5..7d212d7 100644
> --- a/hw/arm/digic_boards.c
> +++ b/hw/arm/digic_boards.c
> @@ -52,7 +52,7 @@ typedef struct DigicBoard {
>  static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size)
>  {
>      memory_region_allocate_system_memory(&s->ram, NULL, "ram", ram_size);
> -    memory_region_add_subregion(get_system_memory(), 0, &s->ram);
> +    memory_region_add_subregion(get_system_memory(), 0, &s->ram, &error_abort);
>  }
>  
>  static void digic4_board_init(DigicBoard *board)
> diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
> index c55fab8..d9f01cf 100644
> --- a/hw/arm/exynos4210.c
> +++ b/hw/arm/exynos4210.c
> @@ -255,7 +255,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
>      memory_region_init_io(&s->chipid_mem, NULL, &exynos4210_chipid_and_omr_ops,
>          NULL, "exynos4210.chipid", sizeof(chipid_and_omr));
>      memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
> -                                &s->chipid_mem);
> +                                &s->chipid_mem, &error_abort);
>  
>      /* Internal ROM */
>      memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom",
> @@ -263,7 +263,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
>      vmstate_register_ram_global(&s->irom_mem);
>      memory_region_set_readonly(&s->irom_mem, true);
>      memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
> -                                &s->irom_mem);
> +                                &s->irom_mem, &error_abort);
>      /* mirror of iROM */
>      memory_region_init_alias(&s->irom_alias_mem, NULL, "exynos4210.irom_alias",
>                               &s->irom_mem,
> @@ -271,14 +271,14 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
>                               EXYNOS4210_IROM_SIZE);
>      memory_region_set_readonly(&s->irom_alias_mem, true);
>      memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
> -                                &s->irom_alias_mem);
> +                                &s->irom_alias_mem, &error_abort);
>  
>      /* Internal RAM */
>      memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
>                             EXYNOS4210_IRAM_SIZE, &error_abort);
>      vmstate_register_ram_global(&s->iram_mem);
>      memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
> -                                &s->iram_mem);
> +                                &s->iram_mem, &error_abort);
>  
>      /* DRAM */
>      mem_size = ram_size;
> @@ -287,14 +287,14 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
>                  mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_abort);
>          vmstate_register_ram_global(&s->dram1_mem);
>          memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
> -                &s->dram1_mem);
> +                &s->dram1_mem, &error_abort);
>          mem_size = EXYNOS4210_DRAM_MAX_SIZE;
>      }
>      memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
>                             &error_abort);
>      vmstate_register_ram_global(&s->dram0_mem);
>      memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
> -            &s->dram0_mem);
> +            &s->dram0_mem, &error_abort);
>  
>     /* PMU.
>      * The only reason of existence at the moment is that secondary CPU boot
> diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
> index f8353a7..aff14d5 100644
> --- a/hw/arm/highbank.c
> +++ b/hw/arm/highbank.c
> @@ -277,12 +277,12 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
>      dram = g_new(MemoryRegion, 1);
>      memory_region_allocate_system_memory(dram, NULL, "highbank.dram", ram_size);
>      /* SDRAM at address zero.  */
> -    memory_region_add_subregion(sysmem, 0, dram);
> +    memory_region_add_subregion(sysmem, 0, dram, &error_abort);
>  
>      sysram = g_new(MemoryRegion, 1);
>      memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000,
>                             &error_abort);
> -    memory_region_add_subregion(sysmem, 0xfff88000, sysram);
> +    memory_region_add_subregion(sysmem, 0xfff88000, sysram, &error_abort);
>      if (bios_name != NULL) {
>          sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>          if (sysboot_filename != NULL) {
> diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
> index 0fbbf99..5a2094e 100644
> --- a/hw/arm/integratorcp.c
> +++ b/hw/arm/integratorcp.c
> @@ -572,10 +572,11 @@ static void integratorcp_init(MachineState *machine)
>      /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
>      /* ??? RAM should repeat to fill physical memory space.  */
>      /* SDRAM at address zero*/
> -    memory_region_add_subregion(address_space_mem, 0, ram);
> +    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
>      /* And again at address 0x80000000 */
>      memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
> -    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
> +    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias,
> +                                &error_abort);
>  
>      dev = qdev_create(NULL, TYPE_INTEGRATOR_CM);
>      qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
> diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
> index 5be0369..5999585 100644
> --- a/hw/arm/kzm.c
> +++ b/hw/arm/kzm.c
> @@ -98,13 +98,16 @@ static void kzm_init(MachineState *machine)
>      /* On a real system, the first 16k is a `secure boot rom' */
>  
>      memory_region_allocate_system_memory(ram, NULL, "kzm.ram", ram_size);
> -    memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
> +    memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram,
> +                                &error_abort);
>  
>      memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
> -    memory_region_add_subregion(address_space_mem, 0x88000000, ram_alias);
> +    memory_region_add_subregion(address_space_mem, 0x88000000, ram_alias,
> +                                &error_abort);
>  
>      memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000, &error_abort);
> -    memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
> +    memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram,
> +                                &error_abort);
>  
>      dev = sysbus_create_varargs("imx_avic", 0x68000000,
>                                  qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
> diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
> index 0da02a6..49850d5 100644
> --- a/hw/arm/mainstone.c
> +++ b/hw/arm/mainstone.c
> @@ -127,7 +127,7 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
>                             &error_abort);
>      vmstate_register_ram_global(rom);
>      memory_region_set_readonly(rom, true);
> -    memory_region_add_subregion(address_space_mem, 0, rom);
> +    memory_region_add_subregion(address_space_mem, 0, rom, &error_abort);
>  
>  #ifdef TARGET_WORDS_BIGENDIAN
>      be = 1;
> diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
> index a3b1314..2456767 100644
> --- a/hw/arm/musicpal.c
> +++ b/hw/arm/musicpal.c
> @@ -1602,12 +1602,13 @@ static void musicpal_init(MachineState *machine)
>      /* For now we use a fixed - the original - RAM size */
>      memory_region_allocate_system_memory(ram, NULL, "musicpal.ram",
>                                           MP_RAM_DEFAULT_SIZE);
> -    memory_region_add_subregion(address_space_mem, 0, ram);
> +    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
>  
>      memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE,
>                             &error_abort);
>      vmstate_register_ram_global(sram);
> -    memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
> +    memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram,
> +                                &error_abort);
>  
>      dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
>                                 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
> diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
> index de2b289..8014014 100644
> --- a/hw/arm/omap1.c
> +++ b/hw/arm/omap1.c
> @@ -271,7 +271,7 @@ static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
>      memory_region_init_io(&s->iomem, NULL, &omap_mpu_timer_ops, s,
>                            "omap-mpu-timer", 0x100);
>  
> -    memory_region_add_subregion(system_memory, base, &s->iomem);
> +    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
>  
>      return s;
>  }
> @@ -399,7 +399,7 @@ static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_wd_timer_ops, s,
>                            "omap-wd-timer", 0x100);
> -    memory_region_add_subregion(memory, base, &s->iomem);
> +    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
>  
>      return s;
>  }
> @@ -506,7 +506,7 @@ static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_os_timer_ops, s,
>                            "omap-os-timer", 0x800);
> -    memory_region_add_subregion(memory, base, &s->iomem);
> +    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
>  
>      return s;
>  }
> @@ -740,7 +740,8 @@ static void omap_ulpd_pm_init(MemoryRegion *system_memory,
>  {
>      memory_region_init_io(&mpu->ulpd_pm_iomem, NULL, &omap_ulpd_pm_ops, mpu,
>                            "omap-ulpd-pm", 0x800);
> -    memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
> +    memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem,
> +                                &error_abort);
>      omap_ulpd_pm_reset(mpu);
>  }
>  
> @@ -963,7 +964,8 @@ static void omap_pin_cfg_init(MemoryRegion *system_memory,
>  {
>      memory_region_init_io(&mpu->pin_cfg_iomem, NULL, &omap_pin_cfg_ops, mpu,
>                            "omap-pin-cfg", 0x800);
> -    memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
> +    memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem,
> +                                &error_abort);
>      omap_pin_cfg_reset(mpu);
>  }
>  
> @@ -1038,14 +1040,17 @@ static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
>                            "omap-id", 0x100000000ULL);
>      memory_region_init_alias(&mpu->id_iomem_e18, NULL, "omap-id-e18", &mpu->id_iomem,
>                               0xfffe1800, 0x800);
> -    memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
> +    memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18,
> +                                &error_abort);
>      memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-ed4", &mpu->id_iomem,
>                               0xfffed400, 0x100);
> -    memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
> +    memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4,
> +                                &error_abort);
>      if (!cpu_is_omap15xx(mpu)) {
>          memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-e20",
>                                   &mpu->id_iomem, 0xfffe2000, 0x800);
> -        memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
> +        memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20,
> +                                    &error_abort);
>      }
>  }
>  
> @@ -1131,7 +1136,7 @@ static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
>  {
>      memory_region_init_io(&mpu->mpui_iomem, NULL, &omap_mpui_ops, mpu,
>                            "omap-mpui", 0x100);
> -    memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
> +    memory_region_add_subregion(memory, base, &mpu->mpui_iomem, &error_abort);
>  
>      omap_mpui_reset(mpu);
>  }
> @@ -1244,7 +1249,7 @@ static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_tipb_bridge_ops, s,
>                            "omap-tipb-bridge", 0x100);
> -    memory_region_add_subregion(memory, base, &s->iomem);
> +    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
>  
>      return s;
>  }
> @@ -1354,7 +1359,7 @@ static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
>  {
>      memory_region_init_io(&mpu->tcmi_iomem, NULL, &omap_tcmi_ops, mpu,
>                            "omap-tcmi", 0x100);
> -    memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
> +    memory_region_add_subregion(memory, base, &mpu->tcmi_iomem, &error_abort);
>      omap_tcmi_reset(mpu);
>  }
>  
> @@ -1440,7 +1445,7 @@ static struct dpll_ctl_s  *omap_dpll_init(MemoryRegion *memory,
>      s->dpll = clk;
>      omap_dpll_reset(s);
>  
> -    memory_region_add_subregion(memory, base, &s->iomem);
> +    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
>      return s;
>  }
>  
> @@ -1861,8 +1866,9 @@ static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
>      omap_clkm_reset(s);
>      s->clkm.cold_start = 0x3a;
>  
> -    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
> -    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
> +    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem, &error_abort);
> +    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem,
> +                                &error_abort);
>  }
>  
>  /* MPU I/O */
> @@ -2110,7 +2116,7 @@ static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s,
>                            "omap-mpuio", 0x800);
> -    memory_region_add_subregion(memory, base, &s->iomem);
> +    memory_region_add_subregion(memory, base, &s->iomem, &error_abort);
>  
>      omap_clk_adduser(clk, qemu_allocate_irq(omap_mpuio_onoff, s, 0));
>  
> @@ -2301,7 +2307,7 @@ static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
>      omap_uwire_reset(s);
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800);
> -    memory_region_add_subregion(system_memory, base, &s->iomem);
> +    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
>  
>      return s;
>  }
> @@ -2415,7 +2421,7 @@ static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s,
>                            "omap-pwl", 0x800);
> -    memory_region_add_subregion(system_memory, base, &s->iomem);
> +    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
>  
>      omap_clk_adduser(clk, qemu_allocate_irq(omap_pwl_clk_update, s, 0));
>      return s;
> @@ -2523,7 +2529,7 @@ static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s,
>                            "omap-pwt", 0x800);
> -    memory_region_add_subregion(system_memory, base, &s->iomem);
> +    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
>      return s;
>  }
>  
> @@ -2943,7 +2949,7 @@ static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,
>                            "omap-rtc", 0x800);
> -    memory_region_add_subregion(system_memory, base, &s->iomem);
> +    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
>  
>      return s;
>  }
> @@ -3480,7 +3486,7 @@ static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
>      omap_mcbsp_reset(s);
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
> -    memory_region_add_subregion(system_memory, base, &s->iomem);
> +    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
>  
>      return s;
>  }
> @@ -3656,7 +3662,7 @@ static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
>      omap_lpg_reset(s);
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800);
> -    memory_region_add_subregion(system_memory, base, &s->iomem);
> +    memory_region_add_subregion(system_memory, base, &s->iomem, &error_abort);
>  
>      omap_clk_adduser(clk, qemu_allocate_irq(omap_lpg_clk_update, s, 0));
>  
> @@ -3697,7 +3703,7 @@ static void omap_setup_mpui_io(MemoryRegion *system_memory,
>      memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu,
>                            "omap-mpui-io", 0x7fff);
>      memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
> -                                &mpu->mpui_io_iomem);
> +                                &mpu->mpui_io_iomem, &error_abort);
>  }
>  
>  /* General chip reset */
> @@ -3777,7 +3783,8 @@ static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
>          io = g_new(MemoryRegion, 1);
>          memory_region_init_alias(io, NULL, map->name,
>                                   system_memory, map->phys_mpu, map->size);
> -        memory_region_add_subregion(system_memory, map->phys_dsp, io);
> +        memory_region_add_subregion(system_memory, map->phys_dsp, io,
> +                                    &error_abort);
>      }
>  }
>  
> @@ -3880,11 +3887,13 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
>      /* Memory-mapped stuff */
>      memory_region_allocate_system_memory(&s->emiff_ram, NULL, "omap1.dram",
>                                           s->sdram_size);
> -    memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
> +    memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram,
> +                                &error_abort);
>      memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
>                             &error_abort);
>      vmstate_register_ram_global(&s->imif_ram);
> -    memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
> +    memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram,
> +                                &error_abort);
>  
>      omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
>  
> diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
> index e39b317..6d70831 100644
> --- a/hw/arm/omap2.c
> +++ b/hw/arm/omap2.c
> @@ -802,7 +802,8 @@ static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
>  
>      memory_region_init_io(&s->iomem_fifo, NULL, &omap_sti_fifo_ops, s,
>                            "omap.sti.fifo", 0x10000);
> -    memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo);
> +    memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo,
> +                                &error_abort);
>  
>      return s;
>  }
> @@ -2274,11 +2275,12 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
>      /* Memory-mapped stuff */
>      memory_region_allocate_system_memory(&s->sdram, NULL, "omap2.dram",
>                                           s->sdram_size);
> -    memory_region_add_subregion(sysmem, OMAP2_Q2_BASE, &s->sdram);
> +    memory_region_add_subregion(sysmem, OMAP2_Q2_BASE, &s->sdram, &error_abort);
>      memory_region_init_ram(&s->sram, NULL, "omap2.sram", s->sram_size,
>                             &error_abort);
>      vmstate_register_ram_global(&s->sram);
> -    memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram);
> +    memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram,
> +                                &error_abort);
>  
>      s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
>  
> diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
> index 4b0f7f9..93be711 100644
> --- a/hw/arm/omap_sx1.c
> +++ b/hw/arm/omap_sx1.c
> @@ -125,23 +125,25 @@ static void sx1_init(MachineState *machine, const int version)
>                             &error_abort);
>      vmstate_register_ram_global(flash);
>      memory_region_set_readonly(flash, true);
> -    memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash);
> +    memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash,
> +                                &error_abort);
>  
>      memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val,
>                            "sx1.cs0", OMAP_CS0_SIZE - flash_size);
>      memory_region_add_subregion(address_space,
> -                                OMAP_CS0_BASE + flash_size, &cs[0]);
> +                                OMAP_CS0_BASE + flash_size, &cs[0],
> +                                &error_abort);
>  
>  
>      memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val,
>                            "sx1.cs2", OMAP_CS2_SIZE);
>      memory_region_add_subregion(address_space,
> -                                OMAP_CS2_BASE, &cs[2]);
> +                                OMAP_CS2_BASE, &cs[2], &error_abort);
>  
>      memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val,
>                            "sx1.cs3", OMAP_CS3_SIZE);
>      memory_region_add_subregion(address_space,
> -                                OMAP_CS2_BASE, &cs[3]);
> +                                OMAP_CS2_BASE, &cs[3], &error_abort);
>  
>      fl_idx = 0;
>  #ifdef TARGET_WORDS_BIGENDIAN
> @@ -169,12 +171,14 @@ static void sx1_init(MachineState *machine, const int version)
>                                 &error_abort);
>          vmstate_register_ram_global(flash_1);
>          memory_region_set_readonly(flash_1, true);
> -        memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1);
> +        memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1,
> +                                    &error_abort);
>  
>          memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
>                                "sx1.cs1", OMAP_CS1_SIZE - flash1_size);
>          memory_region_add_subregion(address_space,
> -                                OMAP_CS1_BASE + flash1_size, &cs[1]);
> +                                OMAP_CS1_BASE + flash1_size, &cs[1],
> +                                &error_abort);
>  
>          if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
>                                     "omap_sx1.flash1-1", flash1_size,
> @@ -189,7 +193,8 @@ static void sx1_init(MachineState *machine, const int version)
>          memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
>                                "sx1.cs1", OMAP_CS1_SIZE);
>          memory_region_add_subregion(address_space,
> -                                OMAP_CS1_BASE, &cs[1]);
> +                                OMAP_CS1_BASE, &cs[1],
> +                                &error_abort);
>      }
>  
>      if (!machine->kernel_filename && !fl_idx && !qtest_enabled()) {
> diff --git a/hw/arm/palm.c b/hw/arm/palm.c
> index 7f1cfb8..7b34ba4 100644
> --- a/hw/arm/palm.c
> +++ b/hw/arm/palm.c
> @@ -216,21 +216,25 @@ static void palmte_init(MachineState *machine)
>                             &error_abort);
>      vmstate_register_ram_global(flash);
>      memory_region_set_readonly(flash, true);
> -    memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);
> +    memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash,
> +                                &error_abort);
>  
>      memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val, "palmte-cs0",
>                            OMAP_CS0_SIZE - flash_size);
>      memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size,
> -                                &cs[0]);
> +                                &cs[0], &error_abort);
>      memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val, "palmte-cs1",
>                            OMAP_CS1_SIZE);
> -    memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]);
> +    memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1],
> +                                &error_abort);
>      memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val, "palmte-cs2",
>                            OMAP_CS2_SIZE);
> -    memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]);
> +    memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2],
> +                                &error_abort);
>      memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val, "palmte-cs3",
>                            OMAP_CS3_SIZE);
> -    memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]);
> +    memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3],
> +                                &error_abort);
>  
>      palmte_microwire_setup(mpu);
>  
> diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
> index ec353f7..8c38a57 100644
> --- a/hw/arm/pxa2xx.c
> +++ b/hw/arm/pxa2xx.c
> @@ -1743,7 +1743,7 @@ static PXA2xxI2SState *pxa2xx_i2s_init(MemoryRegion *sysmem,
>  
>      memory_region_init_io(&s->iomem, NULL, &pxa2xx_i2s_ops, s,
>                            "pxa2xx-i2s", 0x100000);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s);
>  
> @@ -2081,12 +2081,13 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
>      memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size,
>                             &error_abort);
>      vmstate_register_ram_global(&s->sdram);
> -    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
> +    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram,
> +                                &error_abort);
>      memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000,
>                             &error_abort);
>      vmstate_register_ram_global(&s->internal);
>      memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
> -                                &s->internal);
> +                                &s->internal, &error_abort);
>  
>      s->pic = pxa2xx_pic_init(0x40d00000, s->cpu);
>  
> @@ -2138,7 +2139,8 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
>      s->cm_regs[CCCR >> 2] = 0x02000210;	/* 416.0 MHz */
>      s->clkcfg = 0x00000009;		/* Turbo mode active */
>      memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
> -    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
> +    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem,
> +                                &error_abort);
>      vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
>  
>      pxa2xx_setup_cp14(s);
> @@ -2148,12 +2150,14 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
>      s->mm_regs[MDREFR >> 2] = 0x03ca4000;
>      s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */
>      memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);
> -    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);
> +    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem,
> +                                &error_abort);
>      vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
>  
>      s->pm_base = 0x40f00000;
>      memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);
> -    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);
> +    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem,
> +                                &error_abort);
>      vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
>  
>      for (i = 0; pxa27x_ssp[i].io_base; i ++);
> @@ -2215,12 +2219,13 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
>      memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size,
>                             &error_abort);
>      vmstate_register_ram_global(&s->sdram);
> -    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
> +    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram,
> +                                &error_abort);
>      memory_region_init_ram(&s->internal, NULL, "pxa255.internal",
>                             PXA2XX_INTERNAL_SIZE, &error_abort);
>      vmstate_register_ram_global(&s->internal);
>      memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
> -                                &s->internal);
> +                                &s->internal, &error_abort);
>  
>      s->pic = pxa2xx_pic_init(0x40d00000, s->cpu);
>  
> @@ -2271,7 +2276,8 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
>      s->cm_regs[CCCR >> 2] = 0x02000210;	/* 416.0 MHz */
>      s->clkcfg = 0x00000009;		/* Turbo mode active */
>      memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
> -    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
> +    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem,
> +                                &error_abort);
>      vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
>  
>      pxa2xx_setup_cp14(s);
> @@ -2281,12 +2287,14 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
>      s->mm_regs[MDREFR >> 2] = 0x03ca4000;
>      s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */
>      memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);
> -    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);
> +    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem,
> +                                &error_abort);
>      vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
>  
>      s->pm_base = 0x40f00000;
>      memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);
> -    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);
> +    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem,
> +                                &error_abort);
>      vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
>  
>      for (i = 0; pxa255_ssp[i].io_base; i ++);
> diff --git a/hw/arm/realview.c b/hw/arm/realview.c
> index ef2788d..b16c8ae 100644
> --- a/hw/arm/realview.c
> +++ b/hw/arm/realview.c
> @@ -153,7 +153,7 @@ static void realview_init(MachineState *machine,
>          memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size,
>                                 &error_abort);
>          vmstate_register_ram_global(ram_lo);
> -        memory_region_add_subregion(sysmem, 0x20000000, ram_lo);
> +        memory_region_add_subregion(sysmem, 0x20000000, ram_lo, &error_abort);
>      }
>  
>      memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size,
> @@ -165,10 +165,10 @@ static void realview_init(MachineState *machine,
>      /* SDRAM at address zero.  */
>      memory_region_init_alias(ram_alias, NULL, "realview.alias",
>                               ram_hi, 0, low_ram_size);
> -    memory_region_add_subregion(sysmem, 0, ram_alias);
> +    memory_region_add_subregion(sysmem, 0, ram_alias, &error_abort);
>      if (is_pb) {
>          /* And again at a high address.  */
> -        memory_region_add_subregion(sysmem, 0x70000000, ram_hi);
> +        memory_region_add_subregion(sysmem, 0x70000000, ram_hi, &error_abort);
>      } else {
>          ram_size = low_ram_size;
>      }
> @@ -355,7 +355,7 @@ static void realview_init(MachineState *machine,
>      memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000,
>                             &error_abort);
>      vmstate_register_ram_global(ram_hack);
> -    memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack);
> +    memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack, &error_abort);
>  
>      realview_binfo.ram_size = ram_size;
>      realview_binfo.kernel_filename = machine->kernel_filename;
> diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
> index 5bf032a..5e6ac91 100644
> --- a/hw/arm/spitz.c
> +++ b/hw/arm/spitz.c
> @@ -916,7 +916,7 @@ static void spitz_common_init(MachineState *machine,
>      memory_region_init_ram(rom, NULL, "spitz.rom", SPITZ_ROM, &error_abort);
>      vmstate_register_ram_global(rom);
>      memory_region_set_readonly(rom, true);
> -    memory_region_add_subregion(address_space_mem, 0, rom);
> +    memory_region_add_subregion(address_space_mem, 0, rom, &error_abort);
>  
>      /* Setup peripherals */
>      spitz_keyboard_register(mpu);
> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
> index cb515ec..51c3bb9 100644
> --- a/hw/arm/stellaris.c
> +++ b/hw/arm/stellaris.c
> @@ -683,7 +683,8 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
>      s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
>  
>      memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
> -    memory_region_add_subregion(get_system_memory(), base, &s->iomem);
> +    memory_region_add_subregion(get_system_memory(), base, &s->iomem,
> +                                &error_abort);
>      ssys_reset(s);
>      vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
>      return 0;
> @@ -1234,12 +1235,12 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
>                             &error_abort);
>      vmstate_register_ram_global(flash);
>      memory_region_set_readonly(flash, true);
> -    memory_region_add_subregion(system_memory, 0, flash);
> +    memory_region_add_subregion(system_memory, 0, flash, &error_abort);
>  
>      memory_region_init_ram(sram, NULL, "stellaris.sram", sram_size,
>                             &error_abort);
>      vmstate_register_ram_global(sram);
> -    memory_region_add_subregion(system_memory, 0x20000000, sram);
> +    memory_region_add_subregion(system_memory, 0x20000000, sram, &error_abort);
>  
>      pic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
>                        kernel_filename, cpu_model);
> diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
> index 0f3bdc7..996538f 100644
> --- a/hw/arm/stm32f205_soc.c
> +++ b/hw/arm/stm32f205_soc.c
> @@ -80,13 +80,15 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
>      memory_region_set_readonly(flash, true);
>      memory_region_set_readonly(flash_alias, true);
>  
> -    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);
> -    memory_region_add_subregion(system_memory, 0, flash_alias);
> +    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash,
> +                                &error_abort);
> +    memory_region_add_subregion(system_memory, 0, flash_alias, &error_abort);
>  
>      memory_region_init_ram(sram, NULL, "STM32F205.sram", SRAM_SIZE,
>                             &error_abort);
>      vmstate_register_ram_global(sram);
> -    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
> +    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram,
> +                                &error_abort);
>  
>      pic = armv7m_init(get_system_memory(), FLASH_SIZE, 96,
>                        s->kernel_filename, s->cpu_model);
> diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
> index da9fc1d..7b2b970 100644
> --- a/hw/arm/strongarm.c
> +++ b/hw/arm/strongarm.c
> @@ -1608,7 +1608,7 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
>  
>      memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram",
>                                           sdram_size);
> -    memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
> +    memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram, &error_abort);
>  
>      s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
>                      qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
> diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
> index 73572eb..bc56ae0 100644
> --- a/hw/arm/tosa.c
> +++ b/hw/arm/tosa.c
> @@ -230,7 +230,7 @@ static void tosa_init(MachineState *machine)
>      memory_region_init_ram(rom, NULL, "tosa.rom", TOSA_ROM, &error_abort);
>      vmstate_register_ram_global(rom);
>      memory_region_set_readonly(rom, true);
> -    memory_region_add_subregion(address_space_mem, 0, rom);
> +    memory_region_add_subregion(address_space_mem, 0, rom, &error_abort);
>  
>      tmio = tc6393xb_init(address_space_mem, 0x10000000,
>              qdev_get_gpio_in(mpu->gpio, TOSA_GPIO_TC6393XB_INT));
> diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
> index 6c69f4e..82358eb 100644
> --- a/hw/arm/versatilepb.c
> +++ b/hw/arm/versatilepb.c
> @@ -230,7 +230,7 @@ static void versatile_init(MachineState *machine, int board_id)
>                                           machine->ram_size);
>      /* ??? RAM should repeat to fill physical memory space.  */
>      /* SDRAM at address zero.  */
> -    memory_region_add_subregion(sysmem, 0, ram);
> +    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
>  
>      sysctl = qdev_create(NULL, "realview_sysctl");
>      qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004);
> diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
> index da21788..20cd79b 100644
> --- a/hw/arm/vexpress.c
> +++ b/hw/arm/vexpress.c
> @@ -289,8 +289,8 @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
>       * things including ROM or RAM; we always map the RAM there.
>       */
>      memory_region_init_alias(lowram, NULL, "vexpress.lowmem", ram, 0, low_ram_size);
> -    memory_region_add_subregion(sysmem, 0x0, lowram);
> -    memory_region_add_subregion(sysmem, 0x60000000, ram);
> +    memory_region_add_subregion(sysmem, 0x0, lowram, &error_abort);
> +    memory_region_add_subregion(sysmem, 0x60000000, ram, &error_abort);
>  
>      /* 0x1e000000 A9MPCore (SCU) private memory region */
>      init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic, vms->secure);
> @@ -375,7 +375,7 @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
>      memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
>                                           ram_size);
>      /* RAM is from 0x80000000 upwards; there is no low-memory alias for it. */
> -    memory_region_add_subregion(sysmem, 0x80000000, ram);
> +    memory_region_add_subregion(sysmem, 0x80000000, ram, &error_abort);
>  
>      /* 0x2c000000 A15MPCore private memory region (GIC) */
>      init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic, vms->secure);
> @@ -393,7 +393,7 @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
>      memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000,
>                             &error_abort);
>      vmstate_register_ram_global(sram);
> -    memory_region_add_subregion(sysmem, 0x2e000000, sram);
> +    memory_region_add_subregion(sysmem, 0x2e000000, sram, &error_abort);
>  
>      /* 0x7ffb0000: DMA330 DMA controller: not modelled */
>      /* 0x7ffd0000: PL354 static memory controller: not modelled */
> @@ -659,7 +659,8 @@ static void vexpress_common_init(MachineState *machine)
>          flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0);
>          memory_region_init_alias(flashalias, NULL, "vexpress.flashalias",
>                                   flash0mem, 0, VEXPRESS_FLASH_SIZE);
> -        memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias);
> +        memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias,
> +                                    &error_abort);
>      }
>  
>      dinfo = drive_get_next(IF_PFLASH);
> @@ -673,13 +674,13 @@ static void vexpress_common_init(MachineState *machine)
>      memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
>                             &error_abort);
>      vmstate_register_ram_global(sram);
> -    memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
> +    memory_region_add_subregion(sysmem, map[VE_SRAM], sram, &error_abort);
>  
>      vram_size = 0x800000;
>      memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
>                             &error_abort);
>      vmstate_register_ram_global(vram);
> -    memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
> +    memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram, &error_abort);
>  
>      /* 0x4e000000 LAN9118 Ethernet */
>      if (nd_table[0].used) {
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 4846892..8ed9c05 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -685,7 +685,8 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
>      ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
>      memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
>                               ecam_reg, 0, size_ecam);
> -    memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias);
> +    memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias,
> +                                &error_abort);
>  
>      /* Map the MMIO window into system address space so as to expose
>       * the section of PCI MMIO space which starts at the same base address
> @@ -696,7 +697,8 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
>      mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
>      memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
>                               mmio_reg, base_mmio, size_mmio);
> -    memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
> +    memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias,
> +                                &error_abort);
>  
>      /* Map IO port space */
>      sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
> @@ -769,7 +771,8 @@ static void create_platform_bus(VirtBoardInfo *vbi, qemu_irq *pic)
>  
>      memory_region_add_subregion(sysmem,
>                                  platform_bus_params.platform_bus_base,
> -                                sysbus_mmio_get_region(s, 0));
> +                                sysbus_mmio_get_region(s, 0),
> +                                &error_abort);
>  }
>  
>  static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
> @@ -871,7 +874,8 @@ static void machvirt_init(MachineState *machine)
>  
>      memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
>                                           machine->ram_size);
> -    memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
> +    memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram,
> +                                &error_abort);
>  
>      create_flash(vbi);
>  
> diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
> index a4e7b5c..8cbce61 100644
> --- a/hw/arm/xilinx_zynq.c
> +++ b/hw/arm/xilinx_zynq.c
> @@ -163,13 +163,14 @@ static void zynq_init(MachineState *machine)
>      /* DDR remapped to address zero.  */
>      memory_region_allocate_system_memory(ext_ram, NULL, "zynq.ext_ram",
>                                           ram_size);
> -    memory_region_add_subregion(address_space_mem, 0, ext_ram);
> +    memory_region_add_subregion(address_space_mem, 0, ext_ram, &error_abort);
>  
>      /* 256K of on-chip memory */
>      memory_region_init_ram(ocm_ram, NULL, "zynq.ocm_ram", 256 << 10,
>                             &error_abort);
>      vmstate_register_ram_global(ocm_ram);
> -    memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram);
> +    memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram,
> +                                &error_abort);
>  
>      DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
>  
> diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
> index f94da86..ab4dc21 100644
> --- a/hw/arm/xlnx-ep108.c
> +++ b/hw/arm/xlnx-ep108.c
> @@ -58,7 +58,8 @@ static void xlnx_ep108_init(MachineState *machine)
>  
>      memory_region_allocate_system_memory(&s->ddr_ram, NULL, "ddr-ram",
>                                           machine->ram_size);
> -    memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram);
> +    memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram,
> +                                &error_abort);
>  
>      xlnx_ep108_binfo.ram_size = machine->ram_size;
>      xlnx_ep108_binfo.kernel_filename = machine->kernel_filename;
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index 5e72078..c6e6b0a 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -125,7 +125,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
>              addr += XLNX_ZYNQMP_GIC_REGION_SIZE;
>              memory_region_init_alias(alias, OBJECT(s), "zynqmp-gic-alias", mr,
>                                       0, XLNX_ZYNQMP_GIC_REGION_SIZE);
> -            memory_region_add_subregion(system_memory, addr, alias);
> +            memory_region_add_subregion(system_memory, addr, alias,
> +                                        &error_abort);
>          }
>      }
>  
> diff --git a/hw/block/onenand.c b/hw/block/onenand.c
> index 1b2c893..d8a5897 100644
> --- a/hw/block/onenand.c
> +++ b/hw/block/onenand.c
> @@ -120,7 +120,7 @@ static void onenand_mem_setup(OneNANDState *s)
>       * write boot commands.  Also take note of the BWPS bit.  */
>      memory_region_init(&s->container, OBJECT(s), "onenand",
>                         0x10000 << s->shift);
> -    memory_region_add_subregion(&s->container, 0, &s->iomem);
> +    memory_region_add_subregion(&s->container, 0, &s->iomem, &error_abort);
>      memory_region_init_alias(&s->mapped_ram, OBJECT(s), "onenand-mapped-ram",
>                               &s->ram, 0x0200 << s->shift,
>                               0xbe00 << s->shift);
> diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
> index 074a005..100e07c 100644
> --- a/hw/block/pflash_cfi02.c
> +++ b/hw/block/pflash_cfi02.c
> @@ -111,7 +111,8 @@ static void pflash_setup_mappings(pflash_t *pfl)
>      for (i = 0; i < pfl->mappings; ++i) {
>          memory_region_init_alias(&pfl->mem_mappings[i], OBJECT(pfl),
>                                   "pflash-alias", &pfl->orig_mem, 0, size);
> -        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
> +        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i],
> +                                    &error_abort);
>      }
>  }
>  
> diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
> index 36f1c4a..1c0a04d 100644
> --- a/hw/char/debugcon.c
> +++ b/hw/char/debugcon.c
> @@ -106,7 +106,7 @@ static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)
>      memory_region_init_io(&s->io, OBJECT(dev), &debugcon_ops, s,
>                            TYPE_ISA_DEBUGCON_DEVICE, 1);
>      memory_region_add_subregion(isa_address_space_io(d),
> -                                isa->iobase, &s->io);
> +                                isa->iobase, &s->io, &error_abort);
>  }
>  
>  static Property debugcon_isa_properties[] = {
> diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
> index 98fd44e..ecb31a0 100644
> --- a/hw/char/mcf_uart.c
> +++ b/hw/char/mcf_uart.c
> @@ -303,5 +303,5 @@ void mcf_uart_mm_init(MemoryRegion *sysmem,
>  
>      s = mcf_uart_init(irq, chr);
>      memory_region_init_io(&s->iomem, NULL, &mcf_uart_ops, s, "uart", 0x40);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  }
> diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
> index 88f2094..1beb0f3 100644
> --- a/hw/char/omap_uart.c
> +++ b/hw/char/omap_uart.c
> @@ -173,7 +173,7 @@ struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
>  
>      s->ta = ta;
>  
> -    memory_region_add_subregion(sysmem, base + 0x20, &s->iomem);
> +    memory_region_add_subregion(sysmem, base + 0x20, &s->iomem, &error_abort);
>  
>      return s;
>  }
> diff --git a/hw/char/parallel.c b/hw/char/parallel.c
> index c2b553f..72f4ef8 100644
> --- a/hw/char/parallel.c
> +++ b/hw/char/parallel.c
> @@ -606,7 +606,7 @@ bool parallel_mm_init(MemoryRegion *address_space,
>  
>      memory_region_init_io(&s->iomem, NULL, &parallel_mm_ops, s,
>                            "parallel", 8 << it_shift);
> -    memory_region_add_subregion(address_space, base, &s->iomem);
> +    memory_region_add_subregion(address_space, base, &s->iomem, &error_abort);
>      return true;
>  }
>  
> diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
> index 1c8b9be..751979b 100644
> --- a/hw/char/serial-pci.c
> +++ b/hw/char/serial-pci.c
> @@ -123,7 +123,7 @@ static void multi_serial_pci_realize(PCIDevice *dev, Error **errp)
>          pci->name[i] = g_strdup_printf("uart #%d", i+1);
>          memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s,
>                                pci->name[i], 8);
> -        memory_region_add_subregion(&pci->iobar, 8 * i, &s->io);
> +        memory_region_add_subregion(&pci->iobar, 8 * i, &s->io, &error_abort);
>          pci->ports++;
>      }
>  }
> diff --git a/hw/char/serial.c b/hw/char/serial.c
> index 513d73c..a1cedca 100644
> --- a/hw/char/serial.c
> +++ b/hw/char/serial.c
> @@ -904,7 +904,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
>      vmstate_register(NULL, base, &vmstate_serial, s);
>  
>      memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8);
> -    memory_region_add_subregion(system_io, base, &s->io);
> +    memory_region_add_subregion(system_io, base, &s->io, &error_abort);
>  
>      return s;
>  }
> @@ -967,6 +967,6 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
>  
>      memory_region_init_io(&s->io, NULL, &serial_mm_ops[end], s,
>                            "serial", 8 << it_shift);
> -    memory_region_add_subregion(address_space, base, &s->io);
> +    memory_region_add_subregion(address_space, base, &s->io, &error_abort);
>      return s;
>  }
> diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
> index 9328dd1..45dee7b 100644
> --- a/hw/char/sh_serial.c
> +++ b/hw/char/sh_serial.c
> @@ -386,11 +386,13 @@ void sh_serial_init(MemoryRegion *sysmem,
>  
>      memory_region_init_alias(&s->iomem_p4, NULL, "serial-p4", &s->iomem,
>                               0, 0x28);
> -    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4);
> +    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4,
> +                                &error_abort);
>  
>      memory_region_init_alias(&s->iomem_a7, NULL, "serial-a7", &s->iomem,
>                               0, 0x28);
> -    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7);
> +    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7,
> +                                &error_abort);
>  
>      s->chr = chr;
>  
> diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c
> index 70e0518..025af03 100644
> --- a/hw/core/platform-bus.c
> +++ b/hw/core/platform-bus.c
> @@ -159,7 +159,7 @@ static int platform_bus_map_mmio(PlatformBusDevice *pbus, SysBusDevice *sbdev,
>      }
>  
>      /* Map the device's region into our Platform Bus MMIO space */
> -    memory_region_add_subregion(&pbus->mmio, off, sbdev_mr);
> +    memory_region_add_subregion(&pbus->mmio, off, sbdev_mr, &error_abort);
>  
>      return 0;
>  }
> diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
> index 3c58629..d7d2dc3 100644
> --- a/hw/core/sysbus.c
> +++ b/hw/core/sysbus.c
> @@ -147,7 +147,7 @@ static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr,
>      else {
>          memory_region_add_subregion(get_system_memory(),
>                                      addr,
> -                                    dev->mmio[n].memory);
> +                                    dev->mmio[n].memory, &error_abort);
>      }
>  }
>  
> @@ -312,7 +312,7 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
>  void sysbus_add_io(SysBusDevice *dev, hwaddr addr,
>                         MemoryRegion *mem)
>  {
> -    memory_region_add_subregion(get_system_io(), addr, mem);
> +    memory_region_add_subregion(get_system_io(), addr, mem, &error_abort);
>  }
>  
>  MemoryRegion *sysbus_address_space(SysBusDevice *dev)
> diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
> index acc419e..7f4d179 100644
> --- a/hw/cpu/a15mpcore.c
> +++ b/hw/cpu/a15mpcore.c
> @@ -98,9 +98,11 @@ static void a15mp_priv_realize(DeviceState *dev, Error **errp)
>       *  0x6000-0x7fff -- GIC virtual CPU interface (not modelled)
>       */
>      memory_region_add_subregion(&s->container, 0x1000,
> -                                sysbus_mmio_get_region(busdev, 0));
> +                                sysbus_mmio_get_region(busdev, 0),
> +                                &error_abort);
>      memory_region_add_subregion(&s->container, 0x2000,
> -                                sysbus_mmio_get_region(busdev, 1));
> +                                sysbus_mmio_get_region(busdev, 1),
> +                                &error_abort);
>  }
>  
>  static Property a15mp_priv_properties[] = {
> diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
> index c09358c..bb63075 100644
> --- a/hw/cpu/a9mpcore.c
> +++ b/hw/cpu/a9mpcore.c
> @@ -112,21 +112,27 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
>       *  0x1000-0x1fff -- GIC Distributor
>       */
>      memory_region_add_subregion(&s->container, 0,
> -                                sysbus_mmio_get_region(scubusdev, 0));
> +                                sysbus_mmio_get_region(scubusdev, 0),
> +                                &error_abort);
>      /* GIC CPU interface */
>      memory_region_add_subregion(&s->container, 0x100,
> -                                sysbus_mmio_get_region(gicbusdev, 1));
> +                                sysbus_mmio_get_region(gicbusdev, 1),
> +                                &error_abort);
>      memory_region_add_subregion(&s->container, 0x200,
> -                                sysbus_mmio_get_region(gtimerbusdev, 0));
> +                                sysbus_mmio_get_region(gtimerbusdev, 0),
> +                                &error_abort);
>      /* Note that the A9 exposes only the "timer/watchdog for this core"
>       * memory region, not the "timer/watchdog for core X" ones 11MPcore has.
>       */
>      memory_region_add_subregion(&s->container, 0x600,
> -                                sysbus_mmio_get_region(mptimerbusdev, 0));
> +                                sysbus_mmio_get_region(mptimerbusdev, 0),
> +                                &error_abort);
>      memory_region_add_subregion(&s->container, 0x620,
> -                                sysbus_mmio_get_region(wdtbusdev, 0));
> +                                sysbus_mmio_get_region(wdtbusdev, 0),
> +                                &error_abort);
>      memory_region_add_subregion(&s->container, 0x1000,
> -                                sysbus_mmio_get_region(gicbusdev, 0));
> +                                sysbus_mmio_get_region(gicbusdev, 0),
> +                                &error_abort);
>  
>      /* Wire up the interrupt from each watchdog and timer.
>       * For each core the global timer is PPI 27, the private
> diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
> index 717d3e4..987e7ec 100644
> --- a/hw/cpu/arm11mpcore.c
> +++ b/hw/cpu/arm11mpcore.c
> @@ -28,14 +28,16 @@ static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
>      SysBusDevice *wdtbusdev = SYS_BUS_DEVICE(&s->wdtimer);
>  
>      memory_region_add_subregion(&s->container, 0,
> -                                sysbus_mmio_get_region(scubusdev, 0));
> +                                sysbus_mmio_get_region(scubusdev, 0),
> +                                &error_abort);
>      /* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs
>       * at 0x200, 0x300...
>       */
>      for (i = 0; i < (s->num_cpu + 1); i++) {
>          hwaddr offset = 0x100 + (i * 0x100);
>          memory_region_add_subregion(&s->container, offset,
> -                                    sysbus_mmio_get_region(gicbusdev, i + 1));
> +                                    sysbus_mmio_get_region(gicbusdev, i + 1),
> +                                    &error_abort);
>      }
>      /* Add the regions for timer and watchdog for "current CPU" and
>       * for each specific CPU.
> @@ -44,12 +46,15 @@ static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
>          /* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */
>          hwaddr offset = 0x600 + i * 0x100;
>          memory_region_add_subregion(&s->container, offset,
> -                                    sysbus_mmio_get_region(timerbusdev, i));
> +                                    sysbus_mmio_get_region(timerbusdev, i),
> +                                    &error_abort);
>          memory_region_add_subregion(&s->container, offset + 0x20,
> -                                    sysbus_mmio_get_region(wdtbusdev, i));
> +                                    sysbus_mmio_get_region(wdtbusdev, i),
> +                                    &error_abort);
>      }
>      memory_region_add_subregion(&s->container, 0x1000,
> -                                sysbus_mmio_get_region(gicbusdev, 0));
> +                                sysbus_mmio_get_region(gicbusdev, 0),
> +                                &error_abort);
>      /* Wire up the interrupt from each watchdog and timer.
>       * For each core the timer is PPI 29 and the watchdog PPI 30.
>       */
> diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
> index 3cae480..fbe6219 100644
> --- a/hw/cris/axis_dev88.c
> +++ b/hw/cris/axis_dev88.c
> @@ -272,14 +272,16 @@ void axisdev88_init(MachineState *machine)
>      /* allocate RAM */
>      memory_region_allocate_system_memory(phys_ram, NULL, "axisdev88.ram",
>                                           ram_size);
> -    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);
> +    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram,
> +                                &error_abort);
>  
>      /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the 
>         internal memory.  */
>      memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE,
>                             &error_abort);
>      vmstate_register_ram_global(phys_intmem);
> -    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);
> +    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem,
> +                                &error_abort);
>  
>        /* Attach a NAND flash to CS1.  */
>      nand = drive_get(IF_MTD, 0, 0);
> @@ -288,13 +290,13 @@ void axisdev88_init(MachineState *machine)
>      memory_region_init_io(&nand_state.iomem, NULL, &nand_ops, &nand_state,
>                            "nand", 0x05000000);
>      memory_region_add_subregion(address_space_mem, 0x10000000,
> -                                &nand_state.iomem);
> +                                &nand_state.iomem, &error_abort);
>  
>      gpio_state.nand = &nand_state;
>      memory_region_init_io(&gpio_state.iomem, NULL, &gpio_ops, &gpio_state,
>                            "gpio", 0x5c);
>      memory_region_add_subregion(address_space_mem, 0x3001a000,
> -                                &gpio_state.iomem);
> +                                &gpio_state.iomem, &error_abort);
>  
>  
>      dev = qdev_create(NULL, "etraxfs,pic");
> diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
> index 5198037..b2bd4a9 100644
> --- a/hw/display/cirrus_vga.c
> +++ b/hw/display/cirrus_vga.c
> @@ -2892,7 +2892,8 @@ static void cirrus_init_common(CirrusVGAState *s, Object *owner,
>      memory_region_init_io(&s->cirrus_vga_io, owner, &cirrus_vga_io_ops, s,
>                            "cirrus-io", 0x30);
>      memory_region_set_flush_coalesced(&s->cirrus_vga_io);
> -    memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io);
> +    memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io,
> +                                &error_abort);
>  
>      memory_region_init(&s->low_mem_container, owner,
>                         "cirrus-lowmem-container",
> @@ -2900,7 +2901,8 @@ static void cirrus_init_common(CirrusVGAState *s, Object *owner,
>  
>      memory_region_init_io(&s->low_mem, owner, &cirrus_vga_mem_ops, s,
>                            "cirrus-low-memory", 0x20000);
> -    memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
> +    memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem,
> +                                &error_abort);
>      for (i = 0; i < 2; ++i) {
>          static const char *names[] = { "vga.bank0", "vga.bank1" };
>          MemoryRegion *bank = &s->cirrus_bank[i];
> @@ -3036,9 +3038,10 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
>      memory_region_init(&s->pci_bar, OBJECT(dev), "cirrus-pci-bar0", 0x2000000);
>  
>      /* XXX: add byte swapping apertures */
> -    memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
> +    memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io,
> +                                &error_abort);
>      memory_region_add_subregion(&s->pci_bar, 0x1000000,
> -                                &s->cirrus_linear_bitblt_io);
> +                                &s->cirrus_linear_bitblt_io, &error_abort);
>  
>       /* setup memory space */
>       /* memory #0 LFB */
> diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c
> index f1fef27..7cb255e 100644
> --- a/hw/display/omap_dss.c
> +++ b/hw/display/omap_dss.c
> @@ -1073,7 +1073,7 @@ struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
>      omap_l4_attach(ta, 1, &s->iomem_disc1);
>      omap_l4_attach(ta, 2, &s->iomem_rfbi1);
>      omap_l4_attach(ta, 3, &s->iomem_venc1);
> -    memory_region_add_subregion(sysmem, l3_base, &s->iomem_im3);
> +    memory_region_add_subregion(sysmem, l3_base, &s->iomem_im3, &error_abort);
>  
>  #if 0
>      s->state = graphic_console_init(omap_update_display,
> diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
> index fda81ba..63ec081 100644
> --- a/hw/display/omap_lcdc.c
> +++ b/hw/display/omap_lcdc.c
> @@ -404,7 +404,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
>      omap_lcdc_reset(s);
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_lcdc_ops, s, "omap.lcdc", 0x100);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      s->con = graphic_console_init(NULL, 0, &omap_ops, s);
>  
> diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
> index ac3c018..7672aa5 100644
> --- a/hw/display/pxa2xx_lcd.c
> +++ b/hw/display/pxa2xx_lcd.c
> @@ -1001,7 +1001,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
>  
>      memory_region_init_io(&s->iomem, NULL, &pxa2xx_lcdc_ops, s,
>                            "pxa2xx-lcd-controller", 0x00100000);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
>      surface = qemu_console_surface(s->con);
> diff --git a/hw/display/sm501.c b/hw/display/sm501.c
> index 15a5ba8..b7a7fbd 100644
> --- a/hw/display/sm501.c
> +++ b/hw/display/sm501.c
> @@ -1415,23 +1415,24 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
>      vmstate_register_ram_global(&s->local_mem_region);
>      memory_region_set_log(&s->local_mem_region, true, DIRTY_MEMORY_VGA);
>      s->local_mem = memory_region_get_ram_ptr(&s->local_mem_region);
> -    memory_region_add_subregion(address_space_mem, base, &s->local_mem_region);
> +    memory_region_add_subregion(address_space_mem, base, &s->local_mem_region,
> +                                &error_abort);
>  
>      /* map mmio */
>      memory_region_init_io(sm501_system_config, NULL, &sm501_system_config_ops, s,
>                            "sm501-system-config", 0x6c);
>      memory_region_add_subregion(address_space_mem, base + MMIO_BASE_OFFSET,
> -                                sm501_system_config);
> +                                sm501_system_config, &error_abort);
>      memory_region_init_io(sm501_disp_ctrl, NULL, &sm501_disp_ctrl_ops, s,
>                            "sm501-disp-ctrl", 0x1000);
>      memory_region_add_subregion(address_space_mem,
>                                  base + MMIO_BASE_OFFSET + SM501_DC,
> -                                sm501_disp_ctrl);
> +                                sm501_disp_ctrl, &error_abort);
>      memory_region_init_io(sm501_2d_engine, NULL, &sm501_2d_engine_ops, s,
>                            "sm501-2d-engine", 0x54);
>      memory_region_add_subregion(address_space_mem,
>                                  base + MMIO_BASE_OFFSET + SM501_2D_ENGINE,
> -                                sm501_2d_engine);
> +                                sm501_2d_engine, &error_abort);
>  
>      /* bridge to usb host emulation module */
>      dev = qdev_create(NULL, "sysbus-ohci");
> diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
> index f5f3f3e..a2f64ec 100644
> --- a/hw/display/tc6393xb.c
> +++ b/hw/display/tc6393xb.c
> @@ -581,13 +581,14 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
>                           NAND_MFR_TOSHIBA, 0x76);
>  
>      memory_region_init_io(&s->iomem, NULL, &tc6393xb_ops, s, "tc6393xb", 0x10000);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      memory_region_init_ram(&s->vram, NULL, "tc6393xb.vram", 0x100000,
>                             &error_abort);
>      vmstate_register_ram_global(&s->vram);
>      s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
> -    memory_region_add_subregion(sysmem, base + 0x100000, &s->vram);
> +    memory_region_add_subregion(sysmem, base + 0x100000, &s->vram,
> +                                &error_abort);
>      s->scr_width = 480;
>      s->scr_height = 640;
>      s->con = graphic_console_init(NULL, 0, &tc6393xb_gfx_ops, s);
> diff --git a/hw/display/vga-isa-mm.c b/hw/display/vga-isa-mm.c
> index 4efc222..1c58361 100644
> --- a/hw/display/vga-isa-mm.c
> +++ b/hw/display/vga-isa-mm.c
> @@ -116,10 +116,12 @@ static void vga_mm_init(ISAVGAMMState *s, hwaddr vram_base,
>  
>      vmstate_register(NULL, 0, &vmstate_vga_common, s);
>  
> -    memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl);
> +    memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl,
> +                                &error_abort);
>      s->vga.bank_offset = 0;
>      memory_region_add_subregion(address_space,
> -                                vram_base + 0x000a0000, vga_io_memory);
> +                                vram_base + 0x000a0000, vga_io_memory,
> +                                &error_abort);
>      memory_region_set_coalescing(vga_io_memory);
>  }
>  
> diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
> index 1dfa331..504ebb6 100644
> --- a/hw/display/vga-pci.c
> +++ b/hw/display/vga-pci.c
> @@ -212,18 +212,18 @@ void pci_std_vga_mmio_region_init(VGACommonState *s,
>      memory_region_init_io(&subs[0], NULL, &pci_vga_ioport_ops, s,
>                            "vga ioports remapped", PCI_VGA_IOPORT_SIZE);
>      memory_region_add_subregion(parent, PCI_VGA_IOPORT_OFFSET,
> -                                &subs[0]);
> +                                &subs[0], &error_abort);
>  
>      memory_region_init_io(&subs[1], NULL, &pci_vga_bochs_ops, s,
>                            "bochs dispi interface", PCI_VGA_BOCHS_SIZE);
>      memory_region_add_subregion(parent, PCI_VGA_BOCHS_OFFSET,
> -                                &subs[1]);
> +                                &subs[1], &error_abort);
>  
>      if (qext) {
>          memory_region_init_io(&subs[2], NULL, &pci_vga_qext_ops, s,
>                                "qemu extended regs", PCI_VGA_QEXT_SIZE);
>          memory_region_add_subregion(parent, PCI_VGA_QEXT_OFFSET,
> -                                    &subs[2]);
> +                                    &subs[2], &error_abort);
>      }
>  }
>  
> diff --git a/hw/display/vga.c b/hw/display/vga.c
> index b35d523..74bb4ed 100644
> --- a/hw/display/vga.c
> +++ b/hw/display/vga.c
> @@ -2247,6 +2247,7 @@ void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
>      /* XXX: use optimized standard vga accesses */
>      memory_region_add_subregion(system_memory,
>                                  VBE_DISPI_LFB_PHYSICAL_ADDRESS,
> -                                &s->vram_vbe);
> +                                &s->vram_vbe,
> +                                &error_abort);
>      s->vbe_mapped = 1;
>  }
> diff --git a/hw/dma/etraxfs_dma.c b/hw/dma/etraxfs_dma.c
> index 3599513..7fd23dc 100644
> --- a/hw/dma/etraxfs_dma.c
> +++ b/hw/dma/etraxfs_dma.c
> @@ -775,7 +775,8 @@ void *etraxfs_dmac_init(hwaddr base, int nr_channels)
>  
>  	memory_region_init_io(&ctrl->mmio, NULL, &dma_ops, ctrl, "etraxfs-dma",
>  			      nr_channels * 0x2000);
> -	memory_region_add_subregion(get_system_memory(), base, &ctrl->mmio);
> +        memory_region_add_subregion(get_system_memory(), base, &ctrl->mmio,
> +                                    &error_abort);
>  
>  	return ctrl;
>  }
> diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
> index a414029..15087ce 100644
> --- a/hw/dma/i8257.c
> +++ b/hw/dma/i8257.c
> @@ -526,7 +526,7 @@ static void dma_init2(struct dma_cont *d, int base, int dshift,
>      memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d,
>                            "dma-chan", 8 << d->dshift);
>      memory_region_add_subregion(isa_address_space_io(NULL),
> -                                base, &d->channel_io);
> +                                base, &d->channel_io, &error_abort);
>  
>      isa_register_portio_list(NULL, page_base, page_portio_list, d,
>                               "dma-page");
> @@ -538,7 +538,8 @@ static void dma_init2(struct dma_cont *d, int base, int dshift,
>      memory_region_init_io(&d->cont_io, NULL, &cont_io_ops, d, "dma-cont",
>                            8 << d->dshift);
>      memory_region_add_subregion(isa_address_space_io(NULL),
> -                                base + (8 << d->dshift), &d->cont_io);
> +                                base + (8 << d->dshift), &d->cont_io,
> +                                &error_abort);
>  
>      qemu_register_reset(dma_reset, d);
>      dma_reset(d);
> diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
> index 97c57a0..02e7a15 100644
> --- a/hw/dma/omap_dma.c
> +++ b/hw/dma/omap_dma.c
> @@ -1666,7 +1666,7 @@ struct soc_dma_s *omap_dma_init(hwaddr base, qemu_irq *irqs,
>      omap_dma_clk_update(s, 0, 1);
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_dma_ops, s, "omap.dma", memsize);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      mpu->drq = s->dma->drq;
>  
> @@ -2089,7 +2089,7 @@ struct soc_dma_s *omap_dma4_init(hwaddr base, qemu_irq *irqs,
>      omap_dma_clk_update(s, 0, !!s->dma->freq);
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_dma4_ops, s, "omap.dma4", 0x1000);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      mpu->drq = s->dma->drq;
>  
> diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
> index 3efa6de..2340b89 100644
> --- a/hw/dma/rc4030.c
> +++ b/hw/dma/rc4030.c
> @@ -336,7 +336,7 @@ static void rc4030_dma_tt_update(rc4030State *s, uint32_t new_tl_base,
>              rc4030_dma_as_update_one(s, i, dma_tl_contents[i].frame);
>          }
>          memory_region_add_subregion(get_system_memory(), new_tl_base,
> -                                    &s->dma_tt_alias);
> +                                    &s->dma_tt_alias, &error_abort);
>          memory_region_transaction_commit();
>      } else {
>          memory_region_init(&s->dma_tt_alias, OBJECT(s),
> @@ -782,7 +782,7 @@ static void rc4030_realize(DeviceState *dev, Error **errp)
>                                   get_system_memory(), 0, DMA_PAGESIZE);
>          memory_region_set_enabled(&s->dma_mrs[i], false);
>          memory_region_add_subregion(&s->dma_mr, i * DMA_PAGESIZE,
> -                                    &s->dma_mrs[i]);
> +                                    &s->dma_mrs[i], &error_abort);
>      }
>      address_space_init(&s->dma_as, &s->dma_mr, "rc4030-dma");
>  }
> diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
> index 74d22f4..b177355 100644
> --- a/hw/i386/kvm/pci-assign.c
> +++ b/hw/i386/kvm/pci-assign.c
> @@ -267,7 +267,8 @@ static void assigned_dev_iomem_setup(PCIDevice *pci_dev, int region_num,
>      if (e_size > 0) {
>          memory_region_init(&region->container, OBJECT(pci_dev),
>                             "assigned-dev-container", e_size);
> -        memory_region_add_subregion(&region->container, 0, &region->real_iomem);
> +        memory_region_add_subregion(&region->container, 0, &region->real_iomem,
> +                                    &error_abort);
>  
>          /* deal with MSI-X MMIO page */
>          if (real_region->base_addr <= r_dev->msix_table_addr &&
> @@ -301,7 +302,8 @@ static void assigned_dev_ioport_setup(PCIDevice *pci_dev, int region_num,
>      memory_region_init_io(&region->real_iomem, OBJECT(pci_dev),
>                            &assigned_dev_ioport_ops, r_dev->v_addrs + region_num,
>                            "assigned-dev-iomem", size);
> -    memory_region_add_subregion(&region->container, 0, &region->real_iomem);
> +    memory_region_add_subregion(&region->container, 0, &region->real_iomem,
> +                                &error_abort);
>  }
>  
>  static uint32_t assigned_dev_pci_read(PCIDevice *d, int pos, int len)
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index bd79d25..9afc653 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1256,14 +1256,14 @@ FWCfgState *pc_memory_init(MachineState *machine,
>      ram_below_4g = g_malloc(sizeof(*ram_below_4g));
>      memory_region_init_alias(ram_below_4g, NULL, "ram-below-4g", ram,
>                               0, below_4g_mem_size);
> -    memory_region_add_subregion(system_memory, 0, ram_below_4g);
> +    memory_region_add_subregion(system_memory, 0, ram_below_4g, &error_abort);
>      e820_add_entry(0, below_4g_mem_size, E820_RAM);
>      if (above_4g_mem_size > 0) {
>          ram_above_4g = g_malloc(sizeof(*ram_above_4g));
>          memory_region_init_alias(ram_above_4g, NULL, "ram-above-4g", ram,
>                                   below_4g_mem_size, above_4g_mem_size);
>          memory_region_add_subregion(system_memory, 0x100000000ULL,
> -                                    ram_above_4g);
> +                                    ram_above_4g, &error_abort);
>          e820_add_entry(0x100000000ULL, above_4g_mem_size, E820_RAM);
>      }
>  
> @@ -1314,7 +1314,7 @@ FWCfgState *pc_memory_init(MachineState *machine,
>          memory_region_init_hva_range(&pcms->hotplug_memory.mr, OBJECT(pcms),
>                                       "hotplug-memory", hotplug_mem_size);
>          memory_region_add_subregion(system_memory, pcms->hotplug_memory.base,
> -                                    &pcms->hotplug_memory.mr);
> +                                    &pcms->hotplug_memory.mr, &error_abort);
>      }
>  
>      /* Initialize PC system firmware */
> @@ -1418,10 +1418,12 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
>      MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);
>  
>      memory_region_init_io(ioport80_io, NULL, &ioport80_io_ops, NULL, "ioport80", 1);
> -    memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io);
> +    memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io,
> +                                &error_abort);
>  
>      memory_region_init_io(ioportF0_io, NULL, &ioportF0_io_ops, NULL, "ioportF0", 1);
> -    memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io);
> +    memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io,
> +                                &error_abort);
>  
>      /*
>       * Check if an HPET shall be created.
> diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
> index 662d997..4b98777 100644
> --- a/hw/i386/pc_sysfw.c
> +++ b/hw/i386/pc_sysfw.c
> @@ -225,7 +225,7 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
>      /* map all the bios at the top of memory */
>      memory_region_add_subregion(rom_memory,
>                                  (uint32_t)(-bios_size),
> -                                bios);
> +                                bios, &error_abort);
>  }
>  
>  void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index 66fb9d9..ac78f69 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -251,11 +251,13 @@ static void bmdma_setup_bar(PCIIDEState *d)
>          bm = &d->bmdma[i];
>          memory_region_init_io(&bm->extra_io, OBJECT(d), &cmd646_bmdma_ops, bm,
>                                "cmd646-bmdma-bus", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> +        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io,
> +                                    &error_abort);
>          memory_region_init_io(&bm->addr_ioport, OBJECT(d),
>                                &bmdma_addr_ioport_ops, bm,
>                                "cmd646-bmdma-ioport", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> +        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport,
> +                                    &error_abort);
>      }
>  }
>  
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index adb6649..70acfce 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -96,10 +96,12 @@ static void bmdma_setup_bar(PCIIDEState *d)
>  
>          memory_region_init_io(&bm->extra_io, OBJECT(d), &piix_bmdma_ops, bm,
>                                "piix-bmdma", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> +        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io,
> +                                    &error_abort);
>          memory_region_init_io(&bm->addr_ioport, OBJECT(d),
>                                &bmdma_addr_ioport_ops, bm, "bmdma", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> +        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport,
> +                                    &error_abort);
>      }
>  }
>  
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index e2da9ef..5efb906 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -98,10 +98,12 @@ static void bmdma_setup_bar(PCIIDEState *d)
>  
>          memory_region_init_io(&bm->extra_io, OBJECT(d), &via_bmdma_ops, bm,
>                                "via-bmdma", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> +        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io,
> +                                    &error_abort);
>          memory_region_init_io(&bm->addr_ioport, OBJECT(d),
>                                &bmdma_addr_ioport_ops, bm, "bmdma", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> +        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport,
> +                                    &error_abort);
>      }
>  }
>  
> diff --git a/hw/input/pxa2xx_keypad.c b/hw/input/pxa2xx_keypad.c
> index 8501114..e2bde81 100644
> --- a/hw/input/pxa2xx_keypad.c
> +++ b/hw/input/pxa2xx_keypad.c
> @@ -314,7 +314,7 @@ PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
>  
>      memory_region_init_io(&s->iomem, NULL, &pxa2xx_keypad_ops, s,
>                            "pxa2xx-keypad", 0x00100000);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      vmstate_register(NULL, 0, &vmstate_pxa2xx_keypad, s);
>  
> diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
> index 0032b97..e65b66d 100644
> --- a/hw/intc/apic_common.c
> +++ b/hw/intc/apic_common.c
> @@ -309,7 +309,8 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
>      info->realize(dev, errp);
>      if (!mmio_registered) {
>          ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev));
> -        memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory);
> +        memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory,
> +                                    &error_abort);
>          mmio_registered = true;
>      }
>  
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index e13b729..4b0f1c3 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -511,7 +511,7 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
>       */
>      memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
>                            "nvic_sysregs", 0x1000);
> -    memory_region_add_subregion(&s->container, 0, &s->sysregmem);
> +    memory_region_add_subregion(&s->container, 0, &s->sysregmem, &error_abort);
>      /* Alias the GIC region so we can get only the section of it
>       * we need, and layer it on top of the system register region.
>       */
> @@ -523,7 +523,8 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
>      /* Map the whole thing into system memory at the location required
>       * by the v7M architecture.
>       */
> -    memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container);
> +    memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container,
> +                                &error_abort);
>      s->systick.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, systick_timer_tick, s);
>  }
>  
> diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
> index b2a4950..57b6d1f 100644
> --- a/hw/intc/exynos4210_gic.c
> +++ b/hw/intc/exynos4210_gic.c
> @@ -318,7 +318,8 @@ static int exynos4210_gic_init(SysBusDevice *sbd)
>                                   0,
>                                   EXYNOS4210_GIC_CPU_REGION_SIZE);
>          memory_region_add_subregion(&s->cpu_container,
> -                EXYNOS4210_EXT_GIC_CPU_GET_OFFSET(i), &s->cpu_alias[i]);
> +                EXYNOS4210_EXT_GIC_CPU_GET_OFFSET(i), &s->cpu_alias[i],
> +                &error_abort);
>  
>          /* Map Distributor per SMP Core */
>          sprintf(dist_alias_name, "%s%x", dist_prefix, i);
> @@ -328,7 +329,8 @@ static int exynos4210_gic_init(SysBusDevice *sbd)
>                                   0,
>                                   EXYNOS4210_GIC_DIST_REGION_SIZE);
>          memory_region_add_subregion(&s->dist_container,
> -                EXYNOS4210_EXT_GIC_DIST_GET_OFFSET(i), &s->dist_alias[i]);
> +                EXYNOS4210_EXT_GIC_DIST_GET_OFFSET(i), &s->dist_alias[i],
> +                &error_abort);
>      }
>  
>      sysbus_init_mmio(sbd, &s->cpu_container);
> diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
> index 14ab0e3..b9aa8e6 100644
> --- a/hw/intc/openpic.c
> +++ b/hw/intc/openpic.c
> @@ -1401,7 +1401,7 @@ static void map_list(OpenPICState *opp, const MemReg *list, int *count)
>                                opp, list->name, list->size);
>  
>          memory_region_add_subregion(&opp->mem, list->start_addr,
> -                                    &opp->sub_io_mem[*count]);
> +                                    &opp->sub_io_mem[*count], &error_abort);
>  
>          (*count)++;
>          list++;
> diff --git a/hw/intc/realview_gic.c b/hw/intc/realview_gic.c
> index 6c81296..da7dff7 100644
> --- a/hw/intc/realview_gic.c
> +++ b/hw/intc/realview_gic.c
> @@ -43,9 +43,11 @@ static void realview_gic_realize(DeviceState *dev, Error **errp)
>      qdev_init_gpio_in(dev, realview_gic_set_irq, numirq - 32);
>  
>      memory_region_add_subregion(&s->container, 0,
> -                                sysbus_mmio_get_region(busdev, 1));
> +                                sysbus_mmio_get_region(busdev, 1),
> +                                &error_abort);
>      memory_region_add_subregion(&s->container, 0x1000,
> -                                sysbus_mmio_get_region(busdev, 0));
> +                                sysbus_mmio_get_region(busdev, 0),
> +                                &error_abort);
>  }
>  
>  static void realview_gic_init(Object *obj)
> diff --git a/hw/intc/sh_intc.c b/hw/intc/sh_intc.c
> index 55c76e4..56c903f 100644
> --- a/hw/intc/sh_intc.c
> +++ b/hw/intc/sh_intc.c
> @@ -319,11 +319,13 @@ static unsigned int sh_intc_register(MemoryRegion *sysmem,
>  #define SH_INTC_IOMEM_FORMAT "interrupt-controller-%s-%s-%s"
>      snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "p4");
>      memory_region_init_alias(iomem_p4, NULL, name, iomem, INTC_A7(address), 4);
> -    memory_region_add_subregion(sysmem, P4ADDR(address), iomem_p4);
> +    memory_region_add_subregion(sysmem, P4ADDR(address), iomem_p4,
> +                                &error_abort);
>  
>      snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "a7");
>      memory_region_init_alias(iomem_a7, NULL, name, iomem, INTC_A7(address), 4);
> -    memory_region_add_subregion(sysmem, A7ADDR(address), iomem_a7);
> +    memory_region_add_subregion(sysmem, A7ADDR(address), iomem_a7,
> +                                &error_abort);
>  #undef SH_INTC_IOMEM_FORMAT
>  
>      /* used to increment aliases index */
> diff --git a/hw/isa/apm.c b/hw/isa/apm.c
> index 26ab170..f1709db 100644
> --- a/hw/isa/apm.c
> +++ b/hw/isa/apm.c
> @@ -98,5 +98,5 @@ void apm_init(PCIDevice *dev, APMState *apm, apm_ctrl_changed_t callback,
>      /* ioport 0xb2, 0xb3 */
>      memory_region_init_io(&apm->io, OBJECT(dev), &apm_ops, apm, "apm-io", 2);
>      memory_region_add_subregion(pci_address_space_io(dev), APM_CNT_IOPORT,
> -                                &apm->io);
> +                                &apm->io, &error_abort);
>  }
> diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
> index 43e0cd8..b1d311a 100644
> --- a/hw/isa/isa-bus.c
> +++ b/hw/isa/isa-bus.c
> @@ -101,7 +101,8 @@ static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
>  
>  void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
>  {
> -    memory_region_add_subregion(isabus->address_space_io, start, io);
> +    memory_region_add_subregion(isabus->address_space_io, start, io,
> +                                &error_abort);
>      isa_init_ioport(dev, start);
>  }
>  
> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
> index 252e1d7..3db63ea 100644
> --- a/hw/isa/vt82c686.c
> +++ b/hw/isa/vt82c686.c
> @@ -362,13 +362,14 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp)
>      pci_conf[0x91] = s->smb_io_base >> 8;
>      pci_conf[0xd2] = 0x90;
>      pm_smbus_init(&s->dev.qdev, &s->smb);
> -    memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
> +    memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io,
> +                                &error_abort);
>  
>      apm_init(dev, &s->apm, NULL, s);
>  
>      memory_region_init(&s->io, OBJECT(dev), "vt82c686-pm", 64);
>      memory_region_set_enabled(&s->io, false);
> -    memory_region_add_subregion(get_system_io(), 0, &s->io);
> +    memory_region_add_subregion(get_system_io(), 0, &s->io, &error_abort);
>  
>      acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
>      acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
> @@ -458,7 +459,7 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp)
>      /* The floppy also uses 0x3f0 and 0x3f1.
>       * But we do not emulate a floppy, so just set it here. */
>      memory_region_add_subregion(isa_bus->address_space_io, 0x3f0,
> -                                &vt82c->superio);
> +                                &vt82c->superio, &error_abort);
>  
>      qemu_register_reset(vt82c686b_reset, d);
>  }
> diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
> index 70f48d3..ff744fd 100644
> --- a/hw/lm32/lm32_boards.c
> +++ b/hw/lm32/lm32_boards.c
> @@ -113,7 +113,8 @@ static void lm32_evr_init(MachineState *machine)
>  
>      memory_region_allocate_system_memory(phys_ram, NULL, "lm32_evr.sdram",
>                                           ram_size);
> -    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
> +    memory_region_add_subregion(address_space_mem, ram_base, phys_ram,
> +                                &error_abort);
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      /* Spansion S29NS128P */
> @@ -214,7 +215,8 @@ static void lm32_uclinux_init(MachineState *machine)
>  
>      memory_region_allocate_system_memory(phys_ram, NULL,
>                                           "lm32_uclinux.sdram", ram_size);
> -    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
> +    memory_region_add_subregion(address_space_mem, ram_base, phys_ram,
> +                                &error_abort);
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      /* Spansion S29NS128P */
> diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
> index e755f5b..0f35218 100644
> --- a/hw/lm32/milkymist.c
> +++ b/hw/lm32/milkymist.c
> @@ -120,7 +120,8 @@ milkymist_init(MachineState *machine)
>  
>      memory_region_allocate_system_memory(phys_sdram, NULL, "milkymist.sdram",
>                                           sdram_size);
> -    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);
> +    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram,
> +                                &error_abort);
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      /* Numonyx JS28F256J3F105 */
> diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
> index f63ab2b..cba086e 100644
> --- a/hw/m68k/an5206.c
> +++ b/hw/m68k/an5206.c
> @@ -51,12 +51,13 @@ static void an5206_init(MachineState *machine)
>  
>      /* DRAM at address zero */
>      memory_region_allocate_system_memory(ram, NULL, "an5206.ram", ram_size);
> -    memory_region_add_subregion(address_space_mem, 0, ram);
> +    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
>  
>      /* Internal SRAM.  */
>      memory_region_init_ram(sram, NULL, "an5206.sram", 512, &error_abort);
>      vmstate_register_ram_global(sram);
> -    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
> +    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram,
> +                                &error_abort);
>  
>      mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, cpu);
>  
> diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
> index 5b77d93..5561adf 100644
> --- a/hw/m68k/dummy_m68k.c
> +++ b/hw/m68k/dummy_m68k.c
> @@ -44,7 +44,7 @@ static void dummy_m68k_init(MachineState *machine)
>      /* RAM at address zero */
>      memory_region_allocate_system_memory(ram, NULL, "dummy_m68k.ram",
>                                           ram_size);
> -    memory_region_add_subregion(address_space_mem, 0, ram);
> +    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
>  
>      /* Load kernel.  */
>      if (kernel_filename) {
> diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c
> index 1727a46..b0e15c6 100644
> --- a/hw/m68k/mcf5206.c
> +++ b/hw/m68k/mcf5206.c
> @@ -534,7 +534,7 @@ qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, M68kCPU *cpu)
>  
>      memory_region_init_io(&s->iomem, NULL, &m5206_mbar_ops, s,
>                            "mbar", 0x00001000);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      pic = qemu_allocate_irqs(m5206_mbar_set_irq, s, 14);
>      s->timer[0] = m5206_timer_init(pic[9]);
> diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
> index 326a42d..e080ed6 100644
> --- a/hw/m68k/mcf5208.c
> +++ b/hw/m68k/mcf5208.c
> @@ -174,7 +174,7 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
>  
>      /* SDRAMC.  */
>      memory_region_init_io(iomem, NULL, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
> -    memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
> +    memory_region_add_subregion(address_space, 0xfc0a8000, iomem, &error_abort);
>      /* Timers.  */
>      for (i = 0; i < 2; i++) {
>          s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
> @@ -183,7 +183,7 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
>          memory_region_init_io(&s->iomem, NULL, &m5208_timer_ops, s,
>                                "m5208-timer", 0x00004000);
>          memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
> -                                    &s->iomem);
> +                                    &s->iomem, &error_abort);
>          s->irq = pic[4 + i];
>      }
>  }
> @@ -219,12 +219,14 @@ static void mcf5208evb_init(MachineState *machine)
>  
>      /* DRAM at 0x40000000 */
>      memory_region_allocate_system_memory(ram, NULL, "mcf5208.ram", ram_size);
> -    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
> +    memory_region_add_subregion(address_space_mem, 0x40000000, ram,
> +                                &error_abort);
>  
>      /* Internal SRAM.  */
>      memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384, &error_abort);
>      vmstate_register_ram_global(sram);
> -    memory_region_add_subregion(address_space_mem, 0x80000000, sram);
> +    memory_region_add_subregion(address_space_mem, 0x80000000, sram,
> +                                &error_abort);
>  
>      /* Internal peripherals.  */
>      pic = mcf_intc_init(address_space_mem, 0xfc048000, cpu);
> diff --git a/hw/m68k/mcf_intc.c b/hw/m68k/mcf_intc.c
> index f13c7f3..3c6c5e5 100644
> --- a/hw/m68k/mcf_intc.c
> +++ b/hw/m68k/mcf_intc.c
> @@ -162,7 +162,7 @@ qemu_irq *mcf_intc_init(MemoryRegion *sysmem,
>      mcf_intc_reset(s);
>  
>      memory_region_init_io(&s->iomem, NULL, &mcf_intc_ops, s, "mcf", 0x100);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      return qemu_allocate_irqs(mcf_intc_set_irq, s, 64);
>  }
> diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
> index bb04862..8cc9118 100644
> --- a/hw/mem/pc-dimm.c
> +++ b/hw/mem/pc-dimm.c
> @@ -95,7 +95,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
>          goto out;
>      }
>  
> -    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
> +    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr, &error_abort);
>      vmstate_register_ram(mr, dev);
>      numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
>  
> diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
> index ed84a37..19de681 100644
> --- a/hw/microblaze/petalogix_ml605_mmu.c
> +++ b/hw/microblaze/petalogix_ml605_mmu.c
> @@ -94,12 +94,14 @@ petalogix_ml605_init(MachineState *machine)
>      memory_region_init_ram(phys_lmb_bram, NULL, "petalogix_ml605.lmb_bram",
>                             LMB_BRAM_SIZE, &error_abort);
>      vmstate_register_ram_global(phys_lmb_bram);
> -    memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram);
> +    memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram,
> +                                &error_abort);
>  
>      memory_region_init_ram(phys_ram, NULL, "petalogix_ml605.ram", ram_size,
>                             &error_abort);
>      vmstate_register_ram_global(phys_ram);
> -    memory_region_add_subregion(address_space_mem, MEMORY_BASEADDR, phys_ram);
> +    memory_region_add_subregion(address_space_mem, MEMORY_BASEADDR, phys_ram,
> +                                &error_abort);
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      /* 5th parameter 2 means bank-width
> diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
> index 0c2140c..62e6563 100644
> --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
> +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
> @@ -73,12 +73,13 @@ petalogix_s3adsp1800_init(MachineState *machine)
>                             "petalogix_s3adsp1800.lmb_bram", LMB_BRAM_SIZE,
>                             &error_abort);
>      vmstate_register_ram_global(phys_lmb_bram);
> -    memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);
> +    memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram,
> +                                &error_abort);
>  
>      memory_region_init_ram(phys_ram, NULL, "petalogix_s3adsp1800.ram",
>                             ram_size, &error_abort);
>      vmstate_register_ram_global(phys_ram);
> -    memory_region_add_subregion(sysmem, ddr_base, phys_ram);
> +    memory_region_add_subregion(sysmem, ddr_base, phys_ram, &error_abort);
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      pflash_cfi01_register(FLASH_BASEADDR,
> diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
> index 10fcca3..7c630bc 100644
> --- a/hw/mips/gt64xxx_pci.c
> +++ b/hw/mips/gt64xxx_pci.c
> @@ -289,7 +289,8 @@ static void gt64120_isd_mapping(GT64120State *s)
>          s->ISD_length, s->ISD_start, length, start);
>      s->ISD_start = start;
>      s->ISD_length = length;
> -    memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem);
> +    memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem,
> +                                &error_abort);
>  }
>  
>  static void gt64120_pci_mapping(GT64120State *s)
> @@ -309,7 +310,7 @@ static void gt64120_pci_mapping(GT64120State *s)
>              memory_region_init_alias(&s->PCI0IO_mem, OBJECT(s), "pci0-io",
>                                       get_system_io(), 0, s->PCI0IO_length);
>              memory_region_add_subregion(get_system_memory(), s->PCI0IO_start,
> -                                        &s->PCI0IO_mem);
> +                                        &s->PCI0IO_mem, &error_abort);
>          }
>      }
>  
> @@ -329,7 +330,7 @@ static void gt64120_pci_mapping(GT64120State *s)
>                                       &s->pci0_mem, s->PCI0M0_start,
>                                       s->PCI0M0_length);
>              memory_region_add_subregion(get_system_memory(), s->PCI0M0_start,
> -                                        &s->PCI0M0_mem);
> +                                        &s->PCI0M0_mem, &error_abort);
>          }
>      }
>  
> @@ -349,7 +350,7 @@ static void gt64120_pci_mapping(GT64120State *s)
>                                       &s->pci0_mem, s->PCI0M1_start,
>                                       s->PCI0M1_length);
>              memory_region_add_subregion(get_system_memory(), s->PCI0M1_start,
> -                                        &s->PCI0M1_mem);
> +                                        &s->PCI0M1_mem, &error_abort);
>          }
>      }
>  }
> diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
> index dea941a..1ed8d1b 100644
> --- a/hw/mips/mips_fulong2e.c
> +++ b/hw/mips/mips_fulong2e.c
> @@ -308,8 +308,9 @@ static void mips_fulong2e_init(MachineState *machine)
>      vmstate_register_ram_global(bios);
>      memory_region_set_readonly(bios, true);
>  
> -    memory_region_add_subregion(address_space_mem, 0, ram);
> -    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios);
> +    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
> +    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios,
> +                                &error_abort);
>  
>      /* We do not support flash operation, just loading pmon.bin as raw BIOS.
>       * Please use -L to set the BIOS path and -bios to set bios name. */
> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index 9d60633..1c49704 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -181,7 +181,7 @@ static void mips_jazz_init(MachineState *machine,
>      /* allocate RAM */
>      memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
>                                           machine->ram_size);
> -    memory_region_add_subregion(address_space, 0, ram);
> +    memory_region_add_subregion(address_space, 0, ram, &error_abort);
>  
>      memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE,
>                             &error_abort);
> @@ -189,8 +189,10 @@ static void mips_jazz_init(MachineState *machine,
>      memory_region_set_readonly(bios, true);
>      memory_region_init_alias(bios2, NULL, "mips_jazz.bios", bios,
>                               0, MAGNUM_BIOS_SIZE);
> -    memory_region_add_subregion(address_space, 0x1fc00000LL, bios);
> -    memory_region_add_subregion(address_space, 0xfff00000LL, bios2);
> +    memory_region_add_subregion(address_space, 0x1fc00000LL, bios,
> +                                &error_abort);
> +    memory_region_add_subregion(address_space, 0xfff00000LL, bios2,
> +                                &error_abort);
>  
>      /* load the BIOS image. */
>      if (bios_name == NULL)
> @@ -218,17 +220,22 @@ static void mips_jazz_init(MachineState *machine,
>      sysbus_connect_irq(sysbus, 0, env->irq[6]);
>      sysbus_connect_irq(sysbus, 1, env->irq[3]);
>      memory_region_add_subregion(address_space, 0x80000000,
> -                                sysbus_mmio_get_region(sysbus, 0));
> +                                sysbus_mmio_get_region(sysbus, 0),
> +                                &error_abort);
>      memory_region_add_subregion(address_space, 0xf0000000,
> -                                sysbus_mmio_get_region(sysbus, 1));
> +                                sysbus_mmio_get_region(sysbus, 1),
> +                                &error_abort);
>      memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000);
> -    memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
> +    memory_region_add_subregion(address_space, 0x8000d000, dma_dummy,
> +                                &error_abort);
>  
>      /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */
>      memory_region_init(isa_io, NULL, "isa-io", 0x00010000);
>      memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
> -    memory_region_add_subregion(address_space, 0x90000000, isa_io);
> -    memory_region_add_subregion(address_space, 0x91000000, isa_mem);
> +    memory_region_add_subregion(address_space, 0x90000000, isa_io,
> +                                &error_abort);
> +    memory_region_add_subregion(address_space, 0x91000000, isa_mem,
> +                                &error_abort);
>      isa_bus = isa_bus_new(NULL, isa_mem, isa_io);
>  
>      /* ISA devices */
> @@ -256,7 +263,8 @@ static void mips_jazz_init(MachineState *machine,
>              vmstate_register_ram_global(rom_mr);
>              memory_region_set_readonly(rom_mr, true);
>              uint8_t *rom = memory_region_get_ram_ptr(rom_mr);
> -            memory_region_add_subregion(address_space, 0x60000000, rom_mr);
> +            memory_region_add_subregion(address_space, 0x60000000, rom_mr,
> +                                        &error_abort);
>              rom[0] = 0x10; /* Mips G364 */
>          }
>          break;
> @@ -312,12 +320,12 @@ static void mips_jazz_init(MachineState *machine,
>      /* Real time clock */
>      rtc_init(isa_bus, 1980, NULL);
>      memory_region_init_io(rtc, NULL, &rtc_ops, NULL, "rtc", 0x1000);
> -    memory_region_add_subregion(address_space, 0x80004000, rtc);
> +    memory_region_add_subregion(address_space, 0x80004000, rtc, &error_abort);
>  
>      /* Keyboard (i8042) */
>      i8042_mm_init(qdev_get_gpio_in(rc4030, 6), qdev_get_gpio_in(rc4030, 7),
>                    i8042, 0x1000, 0x1);
> -    memory_region_add_subregion(address_space, 0x80005000, i8042);
> +    memory_region_add_subregion(address_space, 0x80005000, i8042, &error_abort);
>  
>      /* Serial ports */
>      if (serial_hds[0]) {
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 3082e75..91863e6 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -552,8 +552,10 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
>      memory_region_init_alias(&s->iomem_hi, NULL, "malta-fpga",
>                               &s->iomem, 0xa00, 0x10000-0xa00);
>  
> -    memory_region_add_subregion(address_space, base, &s->iomem_lo);
> -    memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
> +    memory_region_add_subregion(address_space, base, &s->iomem_lo,
> +                                &error_abort);
> +    memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi,
> +                                &error_abort);
>  
>      s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
>  
> @@ -1005,12 +1007,13 @@ void mips_malta_init(MachineState *machine)
>      /* register RAM at high address where it is undisturbed by IO */
>      memory_region_allocate_system_memory(ram_high, NULL, "mips_malta.ram",
>                                           ram_size);
> -    memory_region_add_subregion(system_memory, 0x80000000, ram_high);
> +    memory_region_add_subregion(system_memory, 0x80000000, ram_high,
> +                                &error_abort);
>  
>      /* alias for pre IO hole access */
>      memory_region_init_alias(ram_low_preio, NULL, "mips_malta_low_preio.ram",
>                               ram_high, 0, MIN(ram_size, (256 << 20)));
> -    memory_region_add_subregion(system_memory, 0, ram_low_preio);
> +    memory_region_add_subregion(system_memory, 0, ram_low_preio, &error_abort);
>  
>      /* alias for post IO hole access, if there is enough RAM */
>      if (ram_size > (512 << 20)) {
> @@ -1019,7 +1022,8 @@ void mips_malta_init(MachineState *machine)
>                                   "mips_malta_low_postio.ram",
>                                   ram_high, 512 << 20,
>                                   ram_size - (512 << 20));
> -        memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio);
> +        memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio,
> +                                    &error_abort);
>      }
>  
>      /* generate SPD EEPROM data */
> @@ -1137,7 +1141,8 @@ void mips_malta_init(MachineState *machine)
>                 memory_region_get_ram_ptr(bios), BIOS_SIZE);
>      }
>      memory_region_set_readonly(bios_copy, true);
> -    memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy);
> +    memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy,
> +                                &error_abort);
>  
>      /* Board ID = 0x420 (Malta Board with CoreLV) */
>      stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);
> diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
> index 61f74a6..d11944f 100644
> --- a/hw/mips/mips_mipssim.c
> +++ b/hw/mips/mips_mipssim.c
> @@ -129,7 +129,8 @@ static void mipsnet_init(int base, qemu_irq irq, NICInfo *nd)
>      sysbus_connect_irq(s, 0, irq);
>      memory_region_add_subregion(get_system_io(),
>                                  base,
> -                                sysbus_mmio_get_region(s, 0));
> +                                sysbus_mmio_get_region(s, 0),
> +                                &error_abort);
>  }
>  
>  static void
> @@ -178,10 +179,11 @@ mips_mipssim_init(MachineState *machine)
>      vmstate_register_ram_global(bios);
>      memory_region_set_readonly(bios, true);
>  
> -    memory_region_add_subregion(address_space_mem, 0, ram);
> +    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
>  
>      /* Map the BIOS / boot exception handler. */
> -    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios);
> +    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios,
> +                                &error_abort);
>      /* Load a BIOS / boot exception handler image. */
>      if (bios_name == NULL)
>          bios_name = BIOS_FILENAME;
> @@ -218,7 +220,8 @@ mips_mipssim_init(MachineState *machine)
>      /* Register 64 KB of ISA IO space at 0x1fd00000. */
>      memory_region_init_alias(isa, NULL, "isa_mmio",
>                               get_system_io(), 0, 0x00010000);
> -    memory_region_add_subregion(get_system_memory(), 0x1fd00000, isa);
> +    memory_region_add_subregion(get_system_memory(), 0x1fd00000, isa,
> +                                &error_abort);
>  
>      /* A single 16450 sits at offset 0x3f8. It is attached to
>         MIPS CPU INT2, which is interrupt 4. */
> diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
> index f4dcacd..cd52d83 100644
> --- a/hw/mips/mips_r4k.c
> +++ b/hw/mips/mips_r4k.c
> @@ -208,10 +208,11 @@ void mips_r4k_init(MachineState *machine)
>      }
>      memory_region_allocate_system_memory(ram, NULL, "mips_r4k.ram", ram_size);
>  
> -    memory_region_add_subregion(address_space_mem, 0, ram);
> +    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
>  
>      memory_region_init_io(iomem, NULL, &mips_qemu_ops, NULL, "mips-qemu", 0x10000);
> -    memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem);
> +    memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem,
> +                                &error_abort);
>  
>      /* Try to load a BIOS image. If this fails, we continue regardless,
>         but initialize the hardware ourselves. When a kernel gets
> @@ -236,7 +237,8 @@ void mips_r4k_init(MachineState *machine)
>                                 &error_abort);
>          vmstate_register_ram_global(bios);
>          memory_region_set_readonly(bios, true);
> -        memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios);
> +        memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios,
> +                                    &error_abort);
>  
>          load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
>      } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
> @@ -272,8 +274,10 @@ void mips_r4k_init(MachineState *machine)
>      memory_region_init_alias(isa_io, NULL, "isa-io",
>                               get_system_io(), 0, 0x00010000);
>      memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
> -    memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io);
> -    memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem);
> +    memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io,
> +                                &error_abort);
> +    memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem,
> +                                &error_abort);
>      isa_bus = isa_bus_new(NULL, isa_mem, get_system_io());
>  
>      /* The PIC is attached to the MIPS CPU INT0 pin */
> diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c
> index 69a1b00..df7142c 100644
> --- a/hw/misc/debugexit.c
> +++ b/hw/misc/debugexit.c
> @@ -43,7 +43,7 @@ static void debug_exit_realizefn(DeviceState *d, Error **errp)
>      memory_region_init_io(&isa->io, OBJECT(dev), &debug_exit_ops, isa,
>                            TYPE_ISA_DEBUG_EXIT_DEVICE, isa->iosize);
>      memory_region_add_subregion(isa_address_space_io(dev),
> -                                isa->iobase, &isa->io);
> +                                isa->iobase, &isa->io, &error_abort);
>  }
>  
>  static Property debug_exit_properties[] = {
> diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
> index cc76989..65178e6 100644
> --- a/hw/misc/ivshmem.c
> +++ b/hw/misc/ivshmem.c
> @@ -356,7 +356,7 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
>      memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2",
>                                 s->ivshmem_size, ptr);
>      vmstate_register_ram(&s->ivshmem, DEVICE(s));
> -    memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
> +    memory_region_add_subregion(&s->bar, 0, &s->ivshmem, &error_abort);
>  
>      /* region for shared memory */
>      pci_register_bar(PCI_DEVICE(s), 2, s->ivshmem_attr, &s->bar);
> @@ -535,7 +535,7 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size)
>          IVSHMEM_DPRINTF("guest h/w addr = %p, size = %" PRIu64 "\n",
>                          map_ptr, s->ivshmem_size);
>  
> -        memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
> +        memory_region_add_subregion(&s->bar, 0, &s->ivshmem, &error_abort);
>  
>          /* only store the fd if it is successfully mapped */
>          s->shm_fd = incoming_fd;
> diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
> index e9037b0..21229ed 100644
> --- a/hw/misc/macio/macio.c
> +++ b/hw/misc/macio/macio.c
> @@ -110,10 +110,10 @@ static void macio_escc_legacy_setup(MacIOState *macio_state)
>          MemoryRegion *port = g_new(MemoryRegion, 1);
>          memory_region_init_alias(port, NULL, "escc-legacy-port",
>                                   macio_state->escc_mem, maps[i+1], 0x2);
> -        memory_region_add_subregion(escc_legacy, maps[i], port);
> +        memory_region_add_subregion(escc_legacy, maps[i], port, &error_abort);
>      }
>  
> -    memory_region_add_subregion(bar, 0x12000, escc_legacy);
> +    memory_region_add_subregion(bar, 0x12000, escc_legacy, &error_abort);
>  }
>  
>  static void macio_bar_setup(MacIOState *macio_state)
> @@ -121,7 +121,8 @@ static void macio_bar_setup(MacIOState *macio_state)
>      MemoryRegion *bar = &macio_state->bar;
>  
>      if (macio_state->escc_mem) {
> -        memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
> +        memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem,
> +                                    &error_abort);
>          macio_escc_legacy_setup(macio_state);
>      }
>  }
> @@ -141,7 +142,8 @@ static void macio_common_realize(PCIDevice *d, Error **errp)
>      }
>      sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
>      memory_region_add_subregion(&s->bar, 0x16000,
> -                                sysbus_mmio_get_region(sysbus_dev, 0));
> +                                sysbus_mmio_get_region(sysbus_dev, 0),
> +                                &error_abort);
>  
>      macio_bar_setup(s);
>      pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
> @@ -185,12 +187,14 @@ static void macio_oldworld_realize(PCIDevice *d, Error **errp)
>      }
>      sysbus_dev = SYS_BUS_DEVICE(&os->nvram);
>      memory_region_add_subregion(&s->bar, 0x60000,
> -                                sysbus_mmio_get_region(sysbus_dev, 0));
> +                                sysbus_mmio_get_region(sysbus_dev, 0),
> +                                &error_abort);
>      pmac_format_nvram_partition(&os->nvram, os->nvram.size);
>  
>      if (s->pic_mem) {
>          /* Heathrow PIC */
> -        memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem);
> +        memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem,
> +                                    &error_abort);
>      }
>  
>      /* IDE buses */
> @@ -214,7 +218,7 @@ static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, size_t ide_size,
>      object_initialize(ide, ide_size, TYPE_MACIO_IDE);
>      qdev_set_parent_bus(DEVICE(ide), sysbus_get_default());
>      memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000),
> -                                &ide->mem);
> +                                &ide->mem, &error_abort);
>      name = g_strdup_printf("ide[%i]", index);
>      object_property_add_child(OBJECT(s), name, OBJECT(ide), NULL);
>      g_free(name);
> @@ -292,7 +296,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp)
>  
>      if (s->pic_mem) {
>          /* OpenPIC */
> -        memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
> +        memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem, &error_abort);
>      }
>  
>      /* IDE buses */
> @@ -311,7 +315,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp)
>      timer_memory = g_new(MemoryRegion, 1);
>      memory_region_init_io(timer_memory, OBJECT(s), &timer_ops, NULL, "timer",
>                            0x1000);
> -    memory_region_add_subregion(&s->bar, 0x15000, timer_memory);
> +    memory_region_add_subregion(&s->bar, 0x15000, timer_memory, &error_abort);
>  }
>  
>  static void macio_newworld_init(Object *obj)
> @@ -339,7 +343,7 @@ static void macio_instance_init(Object *obj)
>      object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL);
>  
>      s->dbdma = DBDMA_init(&dbdma_mem);
> -    memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
> +    memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem, &error_abort);
>  }
>  
>  static const VMStateDescription vmstate_macio_oldworld = {
> diff --git a/hw/misc/omap_gpmc.c b/hw/misc/omap_gpmc.c
> index 74fc91c..dcf6a96 100644
> --- a/hw/misc/omap_gpmc.c
> +++ b/hw/misc/omap_gpmc.c
> @@ -419,9 +419,9 @@ static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
>       * starting from <i>base</i>.  */
>      memory_region_init(&f->container, NULL, "omap-gpmc-file", size);
>      memory_region_add_subregion(&f->container, 0,
> -                                omap_gpmc_cs_memregion(s, cs));
> +                                omap_gpmc_cs_memregion(s, cs), &error_abort);
>      memory_region_add_subregion(get_system_memory(), base,
> -                                &f->container);
> +                                &f->container, &error_abort);
>  }
>  
>  static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
> @@ -830,7 +830,8 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
>              g_malloc0(sizeof(struct omap_gpmc_s));
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
> -    memory_region_add_subregion(get_system_memory(), base, &s->iomem);
> +    memory_region_add_subregion(get_system_memory(), base, &s->iomem,
> +                                &error_abort);
>  
>      s->irq = irq;
>      s->drq = drq;
> diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c
> index 245ceac..3f7b333 100644
> --- a/hw/misc/omap_l4.c
> +++ b/hw/misc/omap_l4.c
> @@ -156,7 +156,8 @@ hwaddr omap_l4_attach(struct omap_target_agent_s *ta,
>  
>      base = ta->bus->base + ta->start[region].offset;
>      if (mr) {
> -        memory_region_add_subregion(ta->bus->address_space, base, mr);
> +        memory_region_add_subregion(ta->bus->address_space, base, mr,
> +                                    &error_abort);
>      }
>  
>      return base;
> diff --git a/hw/misc/omap_sdrc.c b/hw/misc/omap_sdrc.c
> index 3de0c0e..97dfab6 100644
> --- a/hw/misc/omap_sdrc.c
> +++ b/hw/misc/omap_sdrc.c
> @@ -163,7 +163,7 @@ struct omap_sdrc_s *omap_sdrc_init(MemoryRegion *sysmem,
>      omap_sdrc_reset(s);
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_sdrc_ops, s, "omap.sdrc", 0x1000);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      return s;
>  }
> diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c
> index 18e94e0..0c80244 100644
> --- a/hw/misc/pc-testdev.c
> +++ b/hw/misc/pc-testdev.c
> @@ -177,11 +177,12 @@ static void testdev_realizefn(DeviceState *d, Error **errp)
>      memory_region_init_io(&dev->iomem, OBJECT(dev), &test_iomem_ops, dev,
>                            "pc-testdev-iomem", IOMEM_LEN);
>  
> -    memory_region_add_subregion(io,  0xe0,       &dev->ioport);
> -    memory_region_add_subregion(io,  0xe4,       &dev->flush);
> -    memory_region_add_subregion(io,  0xe8,       &dev->ioport_byte);
> -    memory_region_add_subregion(io,  0x2000,     &dev->irq);
> -    memory_region_add_subregion(mem, 0xff000000, &dev->iomem);
> +    memory_region_add_subregion(io,  0xe0,       &dev->ioport, &error_abort);
> +    memory_region_add_subregion(io,  0xe4,       &dev->flush, &error_abort);
> +    memory_region_add_subregion(io,  0xe8,       &dev->ioport_byte,
> +                                &error_abort);
> +    memory_region_add_subregion(io,  0x2000,     &dev->irq, &error_abort);
> +    memory_region_add_subregion(mem, 0xff000000, &dev->iomem, &error_abort);
>  }
>  
>  static void testdev_class_init(ObjectClass *klass, void *data)
> diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
> index 80bcc5b..ca36d7d 100644
> --- a/hw/moxie/moxiesim.c
> +++ b/hw/moxie/moxiesim.c
> @@ -125,11 +125,11 @@ static void moxiesim_init(MachineState *machine)
>      /* Allocate RAM. */
>      memory_region_init_ram(ram, NULL, "moxiesim.ram", ram_size, &error_abort);
>      vmstate_register_ram_global(ram);
> -    memory_region_add_subregion(address_space_mem, ram_base, ram);
> +    memory_region_add_subregion(address_space_mem, ram_base, ram, &error_abort);
>  
>      memory_region_init_ram(rom, NULL, "moxie.rom", 128*0x1000, &error_abort);
>      vmstate_register_ram_global(rom);
> -    memory_region_add_subregion(get_system_memory(), 0x1000, rom);
> +    memory_region_add_subregion(get_system_memory(), 0x1000, rom, &error_abort);
>  
>      if (kernel_filename) {
>          loader_params.ram_size = ram_size;
> diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
> index c57365f..477ad01 100644
> --- a/hw/net/fsl_etsec/etsec.c
> +++ b/hw/net/fsl_etsec/etsec.c
> @@ -450,7 +450,8 @@ DeviceState *etsec_create(hwaddr         base,
>      sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, err_irq);
>  
>      memory_region_add_subregion(mr, base,
> -                                SYS_BUS_DEVICE(dev)->mmio[0].memory);
> +                                SYS_BUS_DEVICE(dev)->mmio[0].memory,
> +                                &error_abort);
>  
>      return dev;
>  }
> diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
> index 0255612..a15f004 100644
> --- a/hw/net/mcf_fec.c
> +++ b/hw/net/mcf_fec.c
> @@ -458,7 +458,7 @@ void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd,
>      s->irq = irq;
>  
>      memory_region_init_io(&s->iomem, NULL, &mcf_fec_ops, s, "fec", 0x400);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      s->conf.macaddr = nd->macaddr;
>      s->conf.peers.ncs[0] = nd->netdev;
> diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> index 1da0657..8d1a5fb 100644
> --- a/hw/openrisc/openrisc_sim.c
> +++ b/hw/openrisc/openrisc_sim.c
> @@ -53,9 +53,9 @@ static void openrisc_sim_net_init(MemoryRegion *address_space,
>      s = SYS_BUS_DEVICE(dev);
>      sysbus_connect_irq(s, 0, irq);
>      memory_region_add_subregion(address_space, base,
> -                                sysbus_mmio_get_region(s, 0));
> +                                sysbus_mmio_get_region(s, 0), &error_abort);
>      memory_region_add_subregion(address_space, descriptors,
> -                                sysbus_mmio_get_region(s, 1));
> +                                sysbus_mmio_get_region(s, 1), &error_abort);
>  }
>  
>  static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
> @@ -116,7 +116,7 @@ static void openrisc_sim_init(MachineState *machine)
>      ram = g_malloc(sizeof(*ram));
>      memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, &error_abort);
>      vmstate_register_ram_global(ram);
> -    memory_region_add_subregion(get_system_memory(), 0, ram);
> +    memory_region_add_subregion(get_system_memory(), 0, ram, &error_abort);
>  
>      cpu_openrisc_pic_init(cpu);
>      cpu_openrisc_clock_init(cpu);
> diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
> index 599768e..c472cc6 100644
> --- a/hw/pci-host/apb.c
> +++ b/hw/pci-host/apb.c
> @@ -684,7 +684,8 @@ PCIBus *pci_apb_init(hwaddr special_base,
>      d = APB_DEVICE(dev);
>  
>      memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
> -    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
> +    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio,
> +                                &error_abort);
>  
>      phb = PCI_HOST_BRIDGE(dev);
>      phb->bus = pci_register_bus(DEVICE(phb), "pci",
> diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
> index bfe707a..e1ff06b 100644
> --- a/hw/pci-host/grackle.c
> +++ b/hw/pci-host/grackle.c
> @@ -80,7 +80,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
>      memory_region_init_alias(&d->pci_hole, OBJECT(s), "pci-hole", &d->pci_mmio,
>                               0x80000000ULL, 0x7e000000ULL);
>      memory_region_add_subregion(address_space_mem, 0x80000000ULL,
> -                                &d->pci_hole);
> +                                &d->pci_hole, &error_abort);
>  
>      phb->bus = pci_register_bus(dev, NULL,
>                                  pci_grackle_set_irq,
> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> index ad55f99..899ca92 100644
> --- a/hw/pci-host/piix.c
> +++ b/hw/pci-host/piix.c
> @@ -355,7 +355,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
>      memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low",
>                               f->ram_memory, 0xa0000, 0x20000);
>      memory_region_set_enabled(&f->low_smram, true);
> -    memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
> +    memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram,
> +                                &error_abort);
>      object_property_add_const_link(qdev_get_machine(), "smram",
>                                     OBJECT(&f->smram), &error_abort);
>  
> diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
> index 613ba73..3de30c8 100644
> --- a/hw/pci-host/ppce500.c
> +++ b/hw/pci-host/ppce500.c
> @@ -251,7 +251,7 @@ static void e500_update_pow(PPCE500PCIState *pci, int idx)
>      name = g_strdup_printf("PCI Outbound Window %d", idx);
>      memory_region_init_alias(mem, OBJECT(pci), name, &pci->busmem, tar,
>                               size);
> -    memory_region_add_subregion(address_space_mem, wbar, mem);
> +    memory_region_add_subregion(address_space_mem, wbar, mem, &error_abort);
>      g_free(name);
>  
>      pci_debug("%s: Added window of size=%#lx from CPU=%#lx to PCI=%#lx\n",
> @@ -471,7 +471,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
>  
>      /* Set up PCI view of memory */
>      memory_region_init(&s->bm, OBJECT(s), "bm-e500", UINT64_MAX);
> -    memory_region_add_subregion(&s->bm, 0x0, &s->busmem);
> +    memory_region_add_subregion(&s->bm, 0x0, &s->busmem, &error_abort);
>      address_space_init(&s->bm_as, &s->bm, "pci-bm");
>      pci_setup_iommu(b, e500_pcihost_set_iommu, s);
>  
> @@ -484,9 +484,12 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
>                            "pci-conf-data", 4);
>      memory_region_init_io(&s->iomem, OBJECT(s), &e500_pci_reg_ops, s,
>                            "pci.reg", PCIE500_REG_SIZE);
> -    memory_region_add_subregion(&s->container, PCIE500_CFGADDR, &h->conf_mem);
> -    memory_region_add_subregion(&s->container, PCIE500_CFGDATA, &h->data_mem);
> -    memory_region_add_subregion(&s->container, PCIE500_REG_BASE, &s->iomem);
> +    memory_region_add_subregion(&s->container, PCIE500_CFGADDR, &h->conf_mem,
> +                                &error_abort);
> +    memory_region_add_subregion(&s->container, PCIE500_CFGDATA, &h->data_mem,
> +                                &error_abort);
> +    memory_region_add_subregion(&s->container, PCIE500_REG_BASE, &s->iomem,
> +                                &error_abort);
>      sysbus_init_mmio(dev, &s->container);
>      pci_bus_set_route_irq_fn(b, e500_route_intx_pin_to_irq);
>  
> diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
> index c63f45d..a5213bc 100644
> --- a/hw/pci-host/prep.c
> +++ b/hw/pci-host/prep.c
> @@ -230,19 +230,21 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp)
>  
>      memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, s,
>                            "pci-conf-idx", 4);
> -    memory_region_add_subregion(&s->pci_io, 0xcf8, &h->conf_mem);
> +    memory_region_add_subregion(&s->pci_io, 0xcf8, &h->conf_mem, &error_abort);
>  
>      memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, s,
>                            "pci-conf-data", 4);
> -    memory_region_add_subregion(&s->pci_io, 0xcfc, &h->data_mem);
> +    memory_region_add_subregion(&s->pci_io, 0xcfc, &h->data_mem, &error_abort);
>  
>      memory_region_init_io(&h->mmcfg, OBJECT(s), &raven_pci_io_ops, s,
>                            "pciio", 0x00400000);
> -    memory_region_add_subregion(address_space_mem, 0x80800000, &h->mmcfg);
> +    memory_region_add_subregion(address_space_mem, 0x80800000, &h->mmcfg,
> +                                &error_abort);
>  
>      memory_region_init_io(&s->pci_intack, OBJECT(s), &raven_intack_ops, s,
>                            "pci-intack", 1);
> -    memory_region_add_subregion(address_space_mem, 0xbffffff0, &s->pci_intack);
> +    memory_region_add_subregion(address_space_mem, 0xbffffff0, &s->pci_intack,
> +                                &error_abort);
>  
>      /* TODO Remove once realize propagates to child devices. */
>      object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp);
> @@ -262,10 +264,12 @@ static void raven_pcihost_initfn(Object *obj)
>      address_space_init(&s->pci_io_as, &s->pci_io, "raven-io");
>  
>      /* CPU address space */
> -    memory_region_add_subregion(address_space_mem, 0x80000000, &s->pci_io);
> +    memory_region_add_subregion(address_space_mem, 0x80000000, &s->pci_io,
> +                                &error_abort);
>      memory_region_add_subregion_overlap(address_space_mem, 0x80000000,
>                                          &s->pci_io_non_contiguous, 1);
> -    memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory);
> +    memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory,
> +                                &error_abort);
>      pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
>                          &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
>  
> @@ -276,8 +280,10 @@ static void raven_pcihost_initfn(Object *obj)
>                               memory_region_size(&s->pci_memory));
>      memory_region_init_alias(&s->bm_ram_alias, obj, "bm-system",
>                               get_system_memory(), 0, 0x80000000);
> -    memory_region_add_subregion(&s->bm, 0         , &s->bm_pci_memory_alias);
> -    memory_region_add_subregion(&s->bm, 0x80000000, &s->bm_ram_alias);
> +    memory_region_add_subregion(&s->bm, 0         , &s->bm_pci_memory_alias,
> +                                &error_abort);
> +    memory_region_add_subregion(&s->bm, 0x80000000, &s->bm_ram_alias,
> +                                &error_abort);
>      address_space_init(&s->bm_as, &s->bm, "raven-bm");
>      pci_setup_iommu(&s->pci_bus, raven_pcihost_set_iommu, s);
>  
> @@ -305,7 +311,7 @@ static void raven_realize(PCIDevice *d, Error **errp)
>                             &error_abort);
>      memory_region_set_readonly(&s->bios, true);
>      memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE),
> -                                &s->bios);
> +                                &s->bios, &error_abort);
>      vmstate_register_ram_global(&s->bios);
>      if (s->bios_name) {
>          filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, s->bios_name);
> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> index bd74094..d9f8d56 100644
> --- a/hw/pci-host/q35.c
> +++ b/hw/pci-host/q35.c
> @@ -494,11 +494,13 @@ static void mch_realize(PCIDevice *d, Error **errp)
>      memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
>                               mch->ram_memory, 0xa0000, 0x20000);
>      memory_region_set_enabled(&mch->low_smram, true);
> -    memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
> +    memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram,
> +                                &error_abort);
>      memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high",
>                               mch->ram_memory, 0xa0000, 0x20000);
>      memory_region_set_enabled(&mch->high_smram, true);
> -    memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram);
> +    memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram,
> +                                &error_abort);
>  
>      memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch),
>                            &tseg_blackhole_ops, NULL,
> @@ -512,7 +514,7 @@ static void mch_realize(PCIDevice *d, Error **errp)
>                               mch->ram_memory, mch->below_4g_mem_size, 0);
>      memory_region_set_enabled(&mch->tseg_window, false);
>      memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size,
> -                                &mch->tseg_window);
> +                                &mch->tseg_window, &error_abort);
>      object_property_add_const_link(qdev_get_machine(), "smram",
>                                     OBJECT(&mch->smram), &error_abort);
>  
> diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
> index f0144eb..8604565 100644
> --- a/hw/pci-host/uninorth.c
> +++ b/hw/pci-host/uninorth.c
> @@ -235,7 +235,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
>      memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio,
>                               0x80000000ULL, 0x10000000ULL);
>      memory_region_add_subregion(address_space_mem, 0x80000000ULL,
> -                                &d->pci_hole);
> +                                &d->pci_hole, &error_abort);
>  
>      h->bus = pci_register_bus(dev, NULL,
>                                pci_unin_set_irq, pci_unin_map_irq,
> @@ -301,7 +301,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
>      memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio,
>                               0x80000000ULL, 0x70000000ULL);
>      memory_region_add_subregion(address_space_mem, 0x80000000ULL,
> -                                &d->pci_hole);
> +                                &d->pci_hole, &error_abort);
>  
>      h->bus = pci_register_bus(dev, NULL,
>                                pci_unin_set_irq, pci_unin_map_irq,
> diff --git a/hw/pci/msix.c b/hw/pci/msix.c
> index 7716bf3..10faae6 100644
> --- a/hw/pci/msix.c
> +++ b/hw/pci/msix.c
> @@ -282,10 +282,12 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
>  
>      memory_region_init_io(&dev->msix_table_mmio, OBJECT(dev), &msix_table_mmio_ops, dev,
>                            "msix-table", table_size);
> -    memory_region_add_subregion(table_bar, table_offset, &dev->msix_table_mmio);
> +    memory_region_add_subregion(table_bar, table_offset, &dev->msix_table_mmio,
> +                                &error_abort);
>      memory_region_init_io(&dev->msix_pba_mmio, OBJECT(dev), &msix_pba_mmio_ops, dev,
>                            "msix-pba", pba_size);
> -    memory_region_add_subregion(pba_bar, pba_offset, &dev->msix_pba_mmio);
> +    memory_region_add_subregion(pba_bar, pba_offset, &dev->msix_pba_mmio,
> +                                &error_abort);
>  
>      return 0;
>  }
> diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
> index d8afba8..432088e 100644
> --- a/hw/pci/pcie_host.c
> +++ b/hw/pci/pcie_host.c
> @@ -114,7 +114,8 @@ void pcie_host_mmcfg_map(PCIExpressHost *e, hwaddr addr,
>  {
>      pcie_host_mmcfg_init(e, size);
>      e->base_addr = addr;
> -    memory_region_add_subregion(get_system_memory(), e->base_addr, &e->mmio);
> +    memory_region_add_subregion(get_system_memory(), e->base_addr, &e->mmio,
> +                                &error_abort);
>  }
>  
>  void pcie_host_mmcfg_update(PCIExpressHost *e,
> diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
> index bfb4d31..fae1542 100644
> --- a/hw/pci/shpc.c
> +++ b/hw/pci/shpc.c
> @@ -644,7 +644,7 @@ int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar, unsigned offset)
>      memory_region_init_io(&shpc->mmio, OBJECT(d), &shpc_mmio_ops,
>                            d, "shpc-mmio", SHPC_SIZEOF(d));
>      shpc_cap_update_dword(d);
> -    memory_region_add_subregion(bar, offset, &shpc->mmio);
> +    memory_region_add_subregion(bar, offset, &shpc->mmio, &error_abort);
>  
>      qbus_set_hotplug_handler(BUS(sec_bus), DEVICE(d), NULL);
>  
> diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
> index a7e1877..3728c72 100644
> --- a/hw/pcmcia/pxa2xx.c
> +++ b/hw/pcmcia/pxa2xx.c
> @@ -166,7 +166,7 @@ static void pxa2xx_pcmcia_initfn(Object *obj)
>      memory_region_init_io(&s->iomem, NULL, &pxa2xx_pcmcia_io_ops, s,
>                            "pxa2xx-pcmcia-io", 0x04000000);
>      memory_region_add_subregion(&s->container_mem, 0x00000000,
> -                                &s->iomem);
> +                                &s->iomem, &error_abort);
>  
>      /* Then next 64 MB is reserved */
>  
> @@ -174,13 +174,13 @@ static void pxa2xx_pcmcia_initfn(Object *obj)
>      memory_region_init_io(&s->attr_iomem, NULL, &pxa2xx_pcmcia_attr_ops, s,
>                            "pxa2xx-pcmcia-attribute", 0x04000000);
>      memory_region_add_subregion(&s->container_mem, 0x08000000,
> -                                &s->attr_iomem);
> +                                &s->attr_iomem, &error_abort);
>  
>      /* Socket Common Memory Space */
>      memory_region_init_io(&s->common_iomem, NULL, &pxa2xx_pcmcia_common_ops, s,
>                            "pxa2xx-pcmcia-common", 0x04000000);
>      memory_region_add_subregion(&s->container_mem, 0x0c000000,
> -                                &s->common_iomem);
> +                                &s->common_iomem, &error_abort);
>  
>      s->slot.irq = qemu_allocate_irq(pxa2xx_pcmcia_set_irq, s, 0);
>  
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index d300846..8aeebc1 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -767,7 +767,7 @@ static qemu_irq *ppce500_init_mpic(MachineState *machine, PPCE500Params *params,
>  
>      s = SYS_BUS_DEVICE(dev);
>      memory_region_add_subregion(ccsr, MPC8544_MPIC_REGS_OFFSET,
> -                                s->mmio[0].memory);
> +                                s->mmio[0].memory, &error_abort);
>  
>      return mpic;
>  }
> @@ -863,7 +863,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
>  
>      /* Register Memory */
>      memory_region_allocate_system_memory(ram, NULL, "mpc8544ds.ram", ram_size);
> -    memory_region_add_subregion(address_space_mem, 0, ram);
> +    memory_region_add_subregion(address_space_mem, 0, ram, &error_abort);
>  
>      dev = qdev_create(NULL, "e500-ccsr");
>      object_property_add_child(qdev_get_machine(), "e500-ccsr",
> @@ -872,7 +872,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
>      ccsr = CCSR(dev);
>      ccsr_addr_space = &ccsr->ccsr_space;
>      memory_region_add_subregion(address_space_mem, params->ccsrbar_base,
> -                                ccsr_addr_space);
> +                                ccsr_addr_space, &error_abort);
>  
>      mpic = ppce500_init_mpic(machine, params, ccsr_addr_space, irqs);
>  
> @@ -894,7 +894,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
>      qdev_init_nofail(dev);
>      s = SYS_BUS_DEVICE(dev);
>      memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET,
> -                                sysbus_mmio_get_region(s, 0));
> +                                sysbus_mmio_get_region(s, 0), &error_abort);
>  
>      /* PCI */
>      dev = qdev_create(NULL, "e500-pcihost");
> @@ -907,7 +907,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
>      }
>  
>      memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET,
> -                                sysbus_mmio_get_region(s, 0));
> +                                sysbus_mmio_get_region(s, 0), &error_abort);
>  
>      pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
>      if (!pci_bus)
> @@ -936,7 +936,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
>          qdev_init_nofail(dev);
>          sysbus_connect_irq(s, 0, mpic[MPC8XXX_GPIO_IRQ]);
>          memory_region_add_subregion(ccsr_addr_space, MPC8XXX_GPIO_OFFSET,
> -                                    sysbus_mmio_get_region(s, 0));
> +                                    sysbus_mmio_get_region(s, 0), &error_abort);
>  
>          /* Power Off GPIO at Pin 0 */
>          poweroff_irq = qemu_allocate_irq(ppce500_power_off, NULL, 0);
> @@ -959,7 +959,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
>  
>          memory_region_add_subregion(address_space_mem,
>                                      params->platform_bus_base,
> -                                    sysbus_mmio_get_region(s, 0));
> +                                    sysbus_mmio_get_region(s, 0), &error_abort);
>      }
>  
>      /* Load kernel. */
> diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
> index 0f3e341..a854926 100644
> --- a/hw/ppc/mac_newworld.c
> +++ b/hw/ppc/mac_newworld.c
> @@ -203,7 +203,7 @@ static void ppc_core99_init(MachineState *machine)
>  
>      /* allocate RAM */
>      memory_region_allocate_system_memory(ram, NULL, "ppc_core99.ram", ram_size);
> -    memory_region_add_subregion(get_system_memory(), 0, ram);
> +    memory_region_add_subregion(get_system_memory(), 0, ram, &error_abort);
>  
>      /* allocate and load BIOS */
>      memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE,
> @@ -214,7 +214,8 @@ static void ppc_core99_init(MachineState *machine)
>          bios_name = PROM_FILENAME;
>      filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>      memory_region_set_readonly(bios, true);
> -    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);
> +    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios,
> +                                &error_abort);
>  
>      /* Load OpenBIOS (ELF) */
>      if (filename) {
> @@ -296,14 +297,17 @@ static void ppc_core99_init(MachineState *machine)
>      /* Register 8 MB of ISA IO space */
>      memory_region_init_alias(isa, NULL, "isa_mmio",
>                               get_system_io(), 0, 0x00800000);
> -    memory_region_add_subregion(get_system_memory(), 0xf2000000, isa);
> +    memory_region_add_subregion(get_system_memory(), 0xf2000000, isa,
> +                                &error_abort);
>  
>      /* UniN init: XXX should be a real device */
>      memory_region_init_io(unin_memory, NULL, &unin_ops, token, "unin", 0x1000);
> -    memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);
> +    memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory,
> +                                &error_abort);
>  
>      memory_region_init_io(unin2_memory, NULL, &unin_ops, token, "unin", 0x1000);
> -    memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory);
> +    memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory,
> +                                &error_abort);
>  
>      openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
>      openpic_irqs[0] =
> diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
> index 99879dd..5118202 100644
> --- a/hw/ppc/mac_oldworld.c
> +++ b/hw/ppc/mac_oldworld.c
> @@ -132,7 +132,7 @@ static void ppc_heathrow_init(MachineState *machine)
>  
>      memory_region_allocate_system_memory(ram, NULL, "ppc_heathrow.ram",
>                                           ram_size);
> -    memory_region_add_subregion(sysmem, 0, ram);
> +    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
>  
>      /* allocate and load BIOS */
>      memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE,
> @@ -143,7 +143,7 @@ static void ppc_heathrow_init(MachineState *machine)
>          bios_name = PROM_FILENAME;
>      filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>      memory_region_set_readonly(bios, true);
> -    memory_region_add_subregion(sysmem, PROM_ADDR, bios);
> +    memory_region_add_subregion(sysmem, PROM_ADDR, bios, &error_abort);
>  
>      /* Load OpenBIOS (ELF) */
>      if (filename) {
> @@ -232,7 +232,7 @@ static void ppc_heathrow_init(MachineState *machine)
>      /* Register 2 MB of ISA IO space */
>      memory_region_init_alias(isa, NULL, "isa_mmio",
>                               get_system_io(), 0, 0x00200000);
> -    memory_region_add_subregion(sysmem, 0xfe000000, isa);
> +    memory_region_add_subregion(sysmem, 0xfe000000, isa, &error_abort);
>  
>      /* XXX: we register only 1 output pin for heathrow PIC */
>      heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> index ec6c4cb..80144e0 100644
> --- a/hw/ppc/ppc405_boards.c
> +++ b/hw/ppc/ppc405_boards.c
> @@ -169,7 +169,7 @@ static void ref405ep_fpga_init(MemoryRegion *sysmem, uint32_t base)
>      fpga = g_malloc0(sizeof(ref405ep_fpga_t));
>      memory_region_init_io(fpga_memory, NULL, &ref405ep_fpga_ops, fpga,
>                            "fpga", 0x00000100);
> -    memory_region_add_subregion(sysmem, base, fpga_memory);
> +    memory_region_add_subregion(sysmem, base, fpga_memory, &error_abort);
>      qemu_register_reset(&ref405ep_fpga_reset, fpga);
>  }
>  
> @@ -217,7 +217,7 @@ static void ref405ep_init(MachineState *machine)
>      sram_size = 512 * 1024;
>      memory_region_init_ram(sram, NULL, "ef405ep.sram", sram_size, &error_abort);
>      vmstate_register_ram_global(sram);
> -    memory_region_add_subregion(sysmem, 0xFFF00000, sram);
> +    memory_region_add_subregion(sysmem, 0xFFF00000, sram, &error_abort);
>      /* allocate and load BIOS */
>  #ifdef DEBUG_BOARD_INIT
>      printf("%s: register BIOS\n", __func__);
> @@ -264,7 +264,8 @@ static void ref405ep_init(MachineState *machine)
>                  exit(1);
>              }
>              bios_size = (bios_size + 0xfff) & ~0xfff;
> -            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
> +            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios,
> +                                        &error_abort);
>          } else if (!qtest_enabled() || kernel_filename != NULL) {
>              error_report("Could not load PowerPC BIOS '%s'", bios_name);
>              exit(1);
> @@ -500,7 +501,7 @@ static void taihu_cpld_init(MemoryRegion *sysmem, uint32_t base)
>  
>      cpld = g_malloc0(sizeof(taihu_cpld_t));
>      memory_region_init_io(cpld_memory, NULL, &taihu_cpld_ops, cpld, "cpld", 0x100);
> -    memory_region_add_subregion(sysmem, base, cpld_memory);
> +    memory_region_add_subregion(sysmem, base, cpld_memory, &error_abort);
>      qemu_register_reset(&taihu_cpld_reset, cpld);
>  }
>  
> @@ -590,7 +591,8 @@ static void taihu_405ep_init(MachineState *machine)
>                  exit(1);
>              }
>              bios_size = (bios_size + 0xfff) & ~0xfff;
> -            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
> +            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios,
> +                                        &error_abort);
>          } else if (!qtest_enabled()) {
>              error_report("Could not load PowerPC BIOS '%s'", bios_name);
>              exit(1);
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index c77434a..d33a2f6 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -393,7 +393,8 @@ static void ppc4xx_opba_init(hwaddr base)
>      printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
>  #endif
>      memory_region_init_io(&opba->io, NULL, &opba_ops, opba, "opba", 0x002);
> -    memory_region_add_subregion(get_system_memory(), base, &opba->io);
> +    memory_region_add_subregion(get_system_memory(), base, &opba->io,
> +                                &error_abort);
>      qemu_register_reset(ppc4xx_opba_reset, opba);
>  }
>  
> @@ -815,7 +816,8 @@ static void ppc405_gpio_init(hwaddr base)
>      printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
>  #endif
>      memory_region_init_io(&gpio->io, NULL, &ppc405_gpio_ops, gpio, "pgio", 0x038);
> -    memory_region_add_subregion(get_system_memory(), base, &gpio->io);
> +    memory_region_add_subregion(get_system_memory(), base, &gpio->io,
> +                                &error_abort);
>      qemu_register_reset(&ppc405_gpio_reset, gpio);
>  }
>  
> @@ -863,7 +865,7 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
>              printf("OCM map ISA %08" PRIx32 "\n", isarc);
>  #endif
>              memory_region_add_subregion(get_system_memory(), isarc,
> -                                        &ocm->isarc_ram);
> +                                        &ocm->isarc_ram, &error_abort);
>          }
>      }
>      if (ocm->dsarc != dsarc ||
> @@ -887,7 +889,7 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
>                  printf("OCM map DSA %08" PRIx32 "\n", dsarc);
>  #endif
>                  memory_region_add_subregion(get_system_memory(), dsarc,
> -                                            &ocm->dsarc_ram);
> +                                            &ocm->dsarc_ram, &error_abort);
>              }
>          }
>      }
> @@ -1226,7 +1228,8 @@ static void ppc405_i2c_init(hwaddr base, qemu_irq irq)
>      printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
>  #endif
>      memory_region_init_io(&i2c->iomem, NULL, &i2c_ops, i2c, "i2c", 0x011);
> -    memory_region_add_subregion(get_system_memory(), base, &i2c->iomem);
> +    memory_region_add_subregion(get_system_memory(), base, &i2c->iomem,
> +                                &error_abort);
>      qemu_register_reset(ppc4xx_i2c_reset, i2c);
>  }
>  
> @@ -1505,7 +1508,8 @@ static void ppc4xx_gpt_init(hwaddr base, qemu_irq irqs[5])
>      printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
>  #endif
>      memory_region_init_io(&gpt->iomem, NULL, &gpt_ops, gpt, "gpt", 0x0d4);
> -    memory_region_add_subregion(get_system_memory(), base, &gpt->iomem);
> +    memory_region_add_subregion(get_system_memory(), base, &gpt->iomem,
> +                                &error_abort);
>      qemu_register_reset(ppc4xx_gpt_reset, gpt);
>  }
>  
> diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
> index 778970a..bc37d8a 100644
> --- a/hw/ppc/ppc440_bamboo.c
> +++ b/hw/ppc/ppc440_bamboo.c
> @@ -229,7 +229,8 @@ static void bamboo_init(MachineState *machine)
>  
>      memory_region_init_alias(isa, NULL, "isa_mmio",
>                               get_system_io(), 0, PPC440EP_PCI_IOLEN);
> -    memory_region_add_subregion(get_system_memory(), PPC440EP_PCI_IO, isa);
> +    memory_region_add_subregion(get_system_memory(), PPC440EP_PCI_IO, isa,
> +                                &error_abort);
>  
>      if (serial_hds[0] != NULL) {
>          serial_mm_init(address_space_mem, 0xef600300, 0, pic[0],
> diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
> index 2f38ff7..efd88e0 100644
> --- a/hw/ppc/ppc4xx_devs.c
> +++ b/hw/ppc/ppc4xx_devs.c
> @@ -433,10 +433,10 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram,
>          memory_region_init(&sdram->containers[n], NULL, "sdram-containers",
>                             sdram_size(bcr));
>          memory_region_add_subregion(&sdram->containers[n], 0,
> -                                    &sdram->ram_memories[n]);
> +                                    &sdram->ram_memories[n], &error_abort);
>          memory_region_add_subregion(get_system_memory(),
>                                      sdram_base(bcr),
> -                                    &sdram->containers[n]);
> +                                    &sdram->containers[n], &error_abort);
>      }
>  }
>  
> diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
> index 0bb3cdb..ddd6845 100644
> --- a/hw/ppc/ppc4xx_pci.c
> +++ b/hw/ppc/ppc4xx_pci.c
> @@ -335,9 +335,12 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
>                            "pci-conf-data", 4);
>      memory_region_init_io(&s->iomem, OBJECT(s), &pci_reg_ops, s,
>                            "pci.reg", PCI_REG_SIZE);
> -    memory_region_add_subregion(&s->container, PCIC0_CFGADDR, &h->conf_mem);
> -    memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem);
> -    memory_region_add_subregion(&s->container, PCI_REG_BASE, &s->iomem);
> +    memory_region_add_subregion(&s->container, PCIC0_CFGADDR, &h->conf_mem,
> +                                &error_abort);
> +    memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem,
> +                                &error_abort);
> +    memory_region_add_subregion(&s->container, PCI_REG_BASE, &s->iomem,
> +                                &error_abort);
>      sysbus_init_mmio(dev, &s->container);
>      qemu_register_reset(ppc4xx_pci_reset, s);
>  
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 998ee2d..1e9758b 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -558,7 +558,7 @@ static void ppc_prep_init(MachineState *machine)
>  
>      /* allocate RAM */
>      memory_region_allocate_system_memory(ram, NULL, "ppc_prep.ram", ram_size);
> -    memory_region_add_subregion(sysmem, 0, ram);
> +    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
>  
>      if (linux_boot) {
>          kernel_base = KERNEL_LOAD_ADDR;
> @@ -676,7 +676,7 @@ static void ppc_prep_init(MachineState *machine)
>      /* PowerPC control and status register group */
>  #if 0
>      memory_region_init_io(xcsr, NULL, &PPC_XCSR_ops, NULL, "ppc-xcsr", 0x1000);
> -    memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr);
> +    memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr, &error_abort);
>  #endif
>  
>      if (usb_enabled()) {
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index f174e5a..de237fc 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1515,14 +1515,14 @@ static void ppc_spapr_init(MachineState *machine)
>      spapr->ram_limit = ram_size;
>      memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram",
>                                           spapr->ram_limit);
> -    memory_region_add_subregion(sysmem, 0, ram);
> +    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
>  
>      if (rma_alloc_size && rma) {
>          rma_region = g_new(MemoryRegion, 1);
>          memory_region_init_ram_ptr(rma_region, NULL, "ppc_spapr.rma",
>                                     rma_alloc_size, rma);
>          vmstate_register_ram_global(rma_region);
> -        memory_region_add_subregion(sysmem, 0, rma_region);
> +        memory_region_add_subregion(sysmem, 0, rma_region, &error_abort);
>      }
>  
>      filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index d4a6150..03fb6c1 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -1183,7 +1183,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
>                               namebuf, &sphb->memspace,
>                               SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size);
>      memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,
> -                                &sphb->memwindow);
> +                                &sphb->memwindow, &error_abort);
>  
>      /* Initialize IO regions */
>      sprintf(namebuf, "%s.io", sphb->dtbusname);
> @@ -1194,7 +1194,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
>      memory_region_init_alias(&sphb->iowindow, OBJECT(sphb), namebuf,
>                               &sphb->iospace, 0, SPAPR_PCI_IO_WIN_SIZE);
>      memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
> -                                &sphb->iowindow);
> +                                &sphb->iowindow, &error_abort);
>  
>      bus = pci_register_bus(dev, NULL,
>                             pci_spapr_set_irq, pci_spapr_map_irq, sphb,
> @@ -1237,7 +1237,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
>      memory_region_init_io(&sphb->msiwindow, NULL, &spapr_msi_ops, spapr,
>                            "msi", msi_window_size);
>      memory_region_add_subregion(&sphb->iommu_root, SPAPR_PCI_MSI_WINDOW,
> -                                &sphb->msiwindow);
> +                                &sphb->msiwindow, &error_abort);
>  
>      pci_setup_iommu(bus, spapr_pci_dma_iommu, sphb);
>  
> @@ -1293,7 +1293,7 @@ static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp)
>  
>      /* Register default 32bit DMA window */
>      memory_region_add_subregion(&sphb->iommu_root, 0,
> -                                spapr_tce_get_iommu(tcet));
> +                                spapr_tce_get_iommu(tcet), &error_abort);
>  }
>  
>  static int spapr_phb_children_reset(Object *child, void *opaque)
> diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
> index 99a1be5..6b9e2af 100644
> --- a/hw/ppc/spapr_pci_vfio.c
> +++ b/hw/ppc/spapr_pci_vfio.c
> @@ -68,7 +68,7 @@ static void spapr_phb_vfio_finish_realize(sPAPRPHBState *sphb, Error **errp)
>  
>      /* Register default 32bit DMA window */
>      memory_region_add_subregion(&sphb->iommu_root, tcet->bus_offset,
> -                                spapr_tce_get_iommu(tcet));
> +                                spapr_tce_get_iommu(tcet), &error_abort);
>  }
>  
>  static void spapr_phb_vfio_reset(DeviceState *qdev)
> diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
> index 439732f..1db90d5 100644
> --- a/hw/ppc/virtex_ml507.c
> +++ b/hw/ppc/virtex_ml507.c
> @@ -223,7 +223,8 @@ static void virtex_init(MachineState *machine)
>      qemu_register_reset(main_cpu_reset, cpu);
>  
>      memory_region_allocate_system_memory(phys_ram, NULL, "ram", ram_size);
> -    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
> +    memory_region_add_subregion(address_space_mem, ram_base, phys_ram,
> +                                &error_abort);
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE,
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index 3d20d6a..1ee08c3 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -162,7 +162,7 @@ static void ccw_init(MachineState *machine)
>      /* allocate RAM for core */
>      memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size, &error_abort);
>      vmstate_register_ram_global(ram);
> -    memory_region_add_subregion(sysmem, 0, ram);
> +    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
>  
>      /* If the size of ram is not on a MEM_SECTION_SIZE boundary,
>         calculate the pad size necessary to force this boundary. */
> diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
> index 1284e77..7d61bfb 100644
> --- a/hw/s390x/s390-virtio.c
> +++ b/hw/s390x/s390-virtio.c
> @@ -295,7 +295,7 @@ static void s390_init(MachineState *machine)
>      /* allocate RAM */
>      memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size, &error_abort);
>      vmstate_register_ram_global(ram);
> -    memory_region_add_subregion(sysmem, 0, ram);
> +    memory_region_add_subregion(sysmem, 0, ram, &error_abort);
>  
>      /* clear virtio region */
>      virtio_region_len = my_ram_size - ram_size;
> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
> index b3a6c5e..db461b8 100644
> --- a/hw/s390x/sclp.c
> +++ b/hw/s390x/sclp.c
> @@ -243,7 +243,8 @@ static void assign_storage(SCCB *sccb)
>  
>              memory_region_init_ram(standby_ram, NULL, id, this_subregion_size, &error_abort);
>              vmstate_register_ram_global(standby_ram);
> -            memory_region_add_subregion(sysmem, offset, standby_ram);
> +            memory_region_add_subregion(sysmem, offset, standby_ram,
> +                                        &error_abort);
>          }
>          /* The specified subregion is no longer in standby */
>          mhd->standby_state_map[(assign_addr - mhd->padded_ram_size)
> diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
> index d072dec..63b6b7d 100644
> --- a/hw/sd/omap_mmc.c
> +++ b/hw/sd/omap_mmc.c
> @@ -590,7 +590,7 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
>      omap_mmc_reset(s);
>  
>      memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc", 0x800);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      /* Instantiate the storage */
>      s->card = sd_init(blk, false);
> diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
> index d1fe6d5..fcad7df 100644
> --- a/hw/sd/pxa2xx_mmci.c
> +++ b/hw/sd/pxa2xx_mmci.c
> @@ -483,7 +483,7 @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
>  
>      memory_region_init_io(&s->iomem, NULL, &pxa2xx_mmci_ops, s,
>                            "pxa2xx-mmci", 0x00100000);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>  
>      /* Instantiate the actual storage */
>      s->card = sd_init(blk, false);
> diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
> index 5e22ed7..96124fe 100644
> --- a/hw/sh4/r2d.c
> +++ b/hw/sh4/r2d.c
> @@ -187,7 +187,7 @@ static qemu_irq *r2d_fpga_init(MemoryRegion *sysmem,
>      s->irl = irl;
>  
>      memory_region_init_io(&s->iomem, NULL, &r2d_fpga_ops, s, "r2d-fpga", 0x40);
> -    memory_region_add_subregion(sysmem, base, &s->iomem);
> +    memory_region_add_subregion(sysmem, base, &s->iomem, &error_abort);
>      return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
>  }
>  
> @@ -257,7 +257,8 @@ static void r2d_init(MachineState *machine)
>      /* Allocate memory space */
>      memory_region_init_ram(sdram, NULL, "r2d.sdram", SDRAM_SIZE, &error_abort);
>      vmstate_register_ram_global(sdram);
> -    memory_region_add_subregion(address_space_mem, SDRAM_BASE, sdram);
> +    memory_region_add_subregion(address_space_mem, SDRAM_BASE, sdram,
> +                                &error_abort);
>      /* Register peripherals */
>      s = sh7750_init(cpu, address_space_mem);
>      irq = r2d_fpga_init(address_space_mem, 0x04000000, sh7750_irl(s));
> diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c
> index 5dda5de..e0a283f 100644
> --- a/hw/sh4/sh7750.c
> +++ b/hw/sh4/sh7750.c
> @@ -735,31 +735,38 @@ SH7750State *sh7750_init(SuperHCPU *cpu, MemoryRegion *sysmem)
>  
>      memory_region_init_alias(&s->iomem_1f0, NULL, "memory-1f0",
>                               &s->iomem, 0x1f000000, 0x1000);
> -    memory_region_add_subregion(sysmem, 0x1f000000, &s->iomem_1f0);
> +    memory_region_add_subregion(sysmem, 0x1f000000, &s->iomem_1f0,
> +                                &error_abort);
>  
>      memory_region_init_alias(&s->iomem_ff0, NULL, "memory-ff0",
>                               &s->iomem, 0x1f000000, 0x1000);
> -    memory_region_add_subregion(sysmem, 0xff000000, &s->iomem_ff0);
> +    memory_region_add_subregion(sysmem, 0xff000000, &s->iomem_ff0,
> +                                &error_abort);
>  
>      memory_region_init_alias(&s->iomem_1f8, NULL, "memory-1f8",
>                               &s->iomem, 0x1f800000, 0x1000);
> -    memory_region_add_subregion(sysmem, 0x1f800000, &s->iomem_1f8);
> +    memory_region_add_subregion(sysmem, 0x1f800000, &s->iomem_1f8,
> +                                &error_abort);
>  
>      memory_region_init_alias(&s->iomem_ff8, NULL, "memory-ff8",
>                               &s->iomem, 0x1f800000, 0x1000);
> -    memory_region_add_subregion(sysmem, 0xff800000, &s->iomem_ff8);
> +    memory_region_add_subregion(sysmem, 0xff800000, &s->iomem_ff8,
> +                                &error_abort);
>  
>      memory_region_init_alias(&s->iomem_1fc, NULL, "memory-1fc",
>                               &s->iomem, 0x1fc00000, 0x1000);
> -    memory_region_add_subregion(sysmem, 0x1fc00000, &s->iomem_1fc);
> +    memory_region_add_subregion(sysmem, 0x1fc00000, &s->iomem_1fc,
> +                                &error_abort);
>  
>      memory_region_init_alias(&s->iomem_ffc, NULL, "memory-ffc",
>                               &s->iomem, 0x1fc00000, 0x1000);
> -    memory_region_add_subregion(sysmem, 0xffc00000, &s->iomem_ffc);
> +    memory_region_add_subregion(sysmem, 0xffc00000, &s->iomem_ffc,
> +                                &error_abort);
>  
>      memory_region_init_io(&s->mmct_iomem, NULL, &sh7750_mmct_ops, s,
>                            "cache-and-tlb", 0x08000000);
> -    memory_region_add_subregion(sysmem, 0xf0000000, &s->mmct_iomem);
> +    memory_region_add_subregion(sysmem, 0xf0000000, &s->mmct_iomem,
> +                                &error_abort);
>  
>      sh_intc_init(sysmem, &s->intc, NR_SOURCES,
>  		 _INTC_ARRAY(mask_registers),
> diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
> index a2f6d9e..68b989e 100644
> --- a/hw/sh4/sh_pci.c
> +++ b/hw/sh4/sh_pci.c
> @@ -67,7 +67,8 @@ static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
>              memory_region_del_subregion(get_system_memory(), &pcic->isa);
>              pcic->iobr = val & 0xfffc0001;
>              memory_region_add_subregion(get_system_memory(),
> -                                        pcic->iobr & 0xfffc0000, &pcic->isa);
> +                                        pcic->iobr & 0xfffc0000, &pcic->isa,
> +                                        &error_abort);
>          }
>          break;
>      case 0x220:
> @@ -145,7 +146,8 @@ static int sh_pci_device_init(SysBusDevice *dev)
>      sysbus_init_mmio(dev, &s->memconfig_p4);
>      sysbus_init_mmio(dev, &s->memconfig_a7);
>      s->iobr = 0xfe240000;
> -    memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
> +    memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa,
> +                                &error_abort);
>  
>      s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
>      return 0;
> diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
> index f93f98e..b6f7af3 100644
> --- a/hw/sh4/shix.c
> +++ b/hw/sh4/shix.c
> @@ -62,15 +62,15 @@ static void shix_init(MachineState *machine)
>      memory_region_init_ram(rom, NULL, "shix.rom", 0x4000, &error_abort);
>      vmstate_register_ram_global(rom);
>      memory_region_set_readonly(rom, true);
> -    memory_region_add_subregion(sysmem, 0x00000000, rom);
> +    memory_region_add_subregion(sysmem, 0x00000000, rom, &error_abort);
>      memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000,
>                             &error_abort);
>      vmstate_register_ram_global(&sdram[0]);
> -    memory_region_add_subregion(sysmem, 0x08000000, &sdram[0]);
> +    memory_region_add_subregion(sysmem, 0x08000000, &sdram[0], &error_abort);
>      memory_region_init_ram(&sdram[1], NULL, "shix.sdram2", 0x01000000,
>                             &error_abort);
>      vmstate_register_ram_global(&sdram[1]);
> -    memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);
> +    memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1], &error_abort);
>  
>      /* Load BIOS in 0 (and access it through P2, 0xA0000000) */
>      if (bios_name == NULL)
> diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
> index 7f5dcd6..2103bd7 100644
> --- a/hw/sparc/leon3.c
> +++ b/hw/sparc/leon3.c
> @@ -152,14 +152,16 @@ static void leon3_generic_hw_init(MachineState *machine)
>      }
>  
>      memory_region_allocate_system_memory(ram, NULL, "leon3.ram", ram_size);
> -    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
> +    memory_region_add_subregion(address_space_mem, 0x40000000, ram,
> +                                &error_abort);
>  
>      /* Allocate BIOS */
>      prom_size = 8 * 1024 * 1024; /* 8Mb */
>      memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size, &error_abort);
>      vmstate_register_ram_global(prom);
>      memory_region_set_readonly(prom, true);
> -    memory_region_add_subregion(address_space_mem, 0x00000000, prom);
> +    memory_region_add_subregion(address_space_mem, 0x00000000, prom,
> +                                &error_abort);
>  
>      /* Load boot prom */
>      if (bios_name == NULL) {
> diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
> index 30cfa0e..7252c83 100644
> --- a/hw/sparc64/sun4u.c
> +++ b/hw/sparc64/sun4u.c
> @@ -874,7 +874,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>      nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59);
>      s = SYS_BUS_DEVICE(nvram);
>      memory_region_add_subregion(get_system_io(), 0x2000,
> -                                sysbus_mmio_get_region(s, 0));
> +                                sysbus_mmio_get_region(s, 0), &error_abort);
>   
>      initrd_size = 0;
>      initrd_addr = 0;
> diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
> index 8ab683d..89bb5a6 100644
> --- a/hw/timer/m48t59.c
> +++ b/hw/timer/m48t59.c
> @@ -698,7 +698,8 @@ Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
>          sysbus_connect_irq(s, 0, IRQ);
>          if (io_base != 0) {
>              memory_region_add_subregion(get_system_io(), io_base,
> -                                        sysbus_mmio_get_region(s, 1));
> +                                        sysbus_mmio_get_region(s, 1),
> +                                        &error_abort);
>          }
>          if (mem_base != 0) {
>              sysbus_mmio_map(s, 0, mem_base);
> diff --git a/hw/timer/sh_timer.c b/hw/timer/sh_timer.c
> index 07f0670..40ed41c 100644
> --- a/hw/timer/sh_timer.c
> +++ b/hw/timer/sh_timer.c
> @@ -325,10 +325,12 @@ void tmu012_init(MemoryRegion *sysmem, hwaddr base,
>  
>      memory_region_init_alias(&s->iomem_p4, NULL, "timer-p4",
>                               &s->iomem, 0, 0x1000);
> -    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4);
> +    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4,
> +                                &error_abort);
>  
>      memory_region_init_alias(&s->iomem_a7, NULL, "timer-a7",
>                               &s->iomem, 0, 0x1000);
> -    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7);
> +    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7,
> +                                &error_abort);
>      /* ??? Save/restore.  */
>  }
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index 0806b5f..3312bce 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -1060,7 +1060,7 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
>      isa_init_irq(&s->busdev, &tis->irq, tis->irq_num);
>  
>      memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),
> -                                TPM_TIS_ADDR_BASE, &s->mmio);
> +                                TPM_TIS_ADDR_BASE, &s->mmio, &error_abort);
>  }
>  
>  static void tpm_tis_initfn(Object *obj)
> diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
> index a059a20..14290af 100644
> --- a/hw/tricore/tricore_testboard.c
> +++ b/hw/tricore/tricore_testboard.c
> @@ -89,12 +89,12 @@ static void tricore_testboard_init(MachineState *machine, int board_id)
>      memory_region_init_ram(pcp_text, NULL, "powerlink_pcp_text.ram", 32*1024, &error_abort);
>      vmstate_register_ram_global(pcp_text);
>  
> -    memory_region_add_subregion(sysmem, 0x80000000, ext_cram);
> -    memory_region_add_subregion(sysmem, 0xa1000000, ext_dram);
> -    memory_region_add_subregion(sysmem, 0xd4000000, int_cram);
> -    memory_region_add_subregion(sysmem, 0xd0000000, int_dram);
> -    memory_region_add_subregion(sysmem, 0xf0050000, pcp_data);
> -    memory_region_add_subregion(sysmem, 0xf0060000, pcp_text);
> +    memory_region_add_subregion(sysmem, 0x80000000, ext_cram, &error_abort);
> +    memory_region_add_subregion(sysmem, 0xa1000000, ext_dram, &error_abort);
> +    memory_region_add_subregion(sysmem, 0xd4000000, int_cram, &error_abort);
> +    memory_region_add_subregion(sysmem, 0xd0000000, int_dram, &error_abort);
> +    memory_region_add_subregion(sysmem, 0xf0050000, pcp_data, &error_abort);
> +    memory_region_add_subregion(sysmem, 0xf0060000, pcp_text, &error_abort);
>  
>      tricoretb_binfo.ram_size = machine->ram_size;
>      tricoretb_binfo.kernel_filename = machine->kernel_filename;
> diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
> index 703e29d..23ffc39 100644
> --- a/hw/unicore32/puv3.c
> +++ b/hw/unicore32/puv3.c
> @@ -66,7 +66,8 @@ static void puv3_soc_init(CPUUniCore32State *env)
>  
>      /* Keyboard (i8042), mouse disabled for nographic */
>      i8042_mm_init(irqs[PUV3_IRQS_PS2_KBD], NULL, i8042, PUV3_REGS_OFFSET, 4);
> -    memory_region_add_subregion(get_system_memory(), PUV3_PS2_BASE, i8042);
> +    memory_region_add_subregion(get_system_memory(), PUV3_PS2_BASE, i8042,
> +                                &error_abort);
>  }
>  
>  static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
> @@ -77,7 +78,8 @@ static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
>      memory_region_init_ram(ram_memory, NULL, "puv3.ram", ram_size,
>                             &error_abort);
>      vmstate_register_ram_global(ram_memory);
> -    memory_region_add_subregion(get_system_memory(), 0, ram_memory);
> +    memory_region_add_subregion(get_system_memory(), 0, ram_memory,
> +                                &error_abort);
>  }
>  
>  static const GraphicHwOps no_ops;
> diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
> index cd1cc14..c487cec 100644
> --- a/hw/usb/hcd-ehci-sysbus.c
> +++ b/hw/usb/hcd-ehci-sysbus.c
> @@ -194,7 +194,7 @@ static void fusbh200_ehci_init(Object *obj)
>                            "fusbh200", 0x4c);
>      memory_region_add_subregion(&s->mem,
>                                  s->opregbase + s->portscbase + 4 * s->portnr,
> -                                &f->mem_vendor);
> +                                &f->mem_vendor, &error_abort);
>  }
>  
>  static void fusbh200_ehci_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
> index d7cd40b..2f3f960 100644
> --- a/hw/usb/hcd-ehci.c
> +++ b/hw/usb/hcd-ehci.c
> @@ -2522,10 +2522,12 @@ void usb_ehci_init(EHCIState *s, DeviceState *dev)
>      memory_region_init_io(&s->mem_ports, OBJECT(dev), &ehci_mmio_port_ops, s,
>                            "ports", 4 * s->portnr);
>  
> -    memory_region_add_subregion(&s->mem, s->capsbase, &s->mem_caps);
> -    memory_region_add_subregion(&s->mem, s->opregbase, &s->mem_opreg);
> +    memory_region_add_subregion(&s->mem, s->capsbase, &s->mem_caps,
> +                                &error_abort);
> +    memory_region_add_subregion(&s->mem, s->opregbase, &s->mem_opreg,
> +                                &error_abort);
>      memory_region_add_subregion(&s->mem, s->opregbase + s->portscbase,
> -                                &s->mem_ports);
> +                                &s->mem_ports, &error_abort);
>  }
>  
>  /*
> diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
> index 90a5fbf..efe29ca 100644
> --- a/hw/usb/hcd-xhci.c
> +++ b/hw/usb/hcd-xhci.c
> @@ -3622,10 +3622,14 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
>      memory_region_init_io(&xhci->mem_doorbell, OBJECT(xhci), &xhci_doorbell_ops, xhci,
>                            "doorbell", LEN_DOORBELL);
>  
> -    memory_region_add_subregion(&xhci->mem, 0,            &xhci->mem_cap);
> -    memory_region_add_subregion(&xhci->mem, OFF_OPER,     &xhci->mem_oper);
> -    memory_region_add_subregion(&xhci->mem, OFF_RUNTIME,  &xhci->mem_runtime);
> -    memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell);
> +    memory_region_add_subregion(&xhci->mem, 0,            &xhci->mem_cap,
> +                                &error_abort);
> +    memory_region_add_subregion(&xhci->mem, OFF_OPER,     &xhci->mem_oper,
> +                                &error_abort);
> +    memory_region_add_subregion(&xhci->mem, OFF_RUNTIME,  &xhci->mem_runtime,
> +                                &error_abort);
> +    memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell,
> +                                &error_abort);
>  
>      for (i = 0; i < xhci->numports; i++) {
>          XHCIPort *port = &xhci->ports[i];
> @@ -3633,7 +3637,8 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
>          port->xhci = xhci;
>          memory_region_init_io(&port->mem, OBJECT(xhci), &xhci_port_ops, port,
>                                port->name, 0x10);
> -        memory_region_add_subregion(&xhci->mem, offset, &port->mem);
> +        memory_region_add_subregion(&xhci->mem, offset, &port->mem,
> +                                    &error_abort);
>      }
>  
>      pci_register_bar(dev, 0,
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index 85ee9b0..51aea6d 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -525,7 +525,7 @@ empty_region:
>          memory_region_init(submem, obj, name, 0);
>      }
>  
> -    memory_region_add_subregion(mem, offset, submem);
> +    memory_region_add_subregion(mem, offset, submem, &error_abort);
>  
>      return ret;
>  }
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 2ed877f..f266567 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -1430,7 +1430,8 @@ static void vfio_vga_probe_ati_3c3_quirk(VFIOPCIDevice *vdev)
>      memory_region_init_io(&quirk->mem, OBJECT(vdev), &vfio_ati_3c3_quirk, quirk,
>                            "vfio-ati-3c3-quirk", 1);
>      memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,
> -                                3 /* offset 3 bytes from 0x3c0 */, &quirk->mem);
> +                                3 /* offset 3 bytes from 0x3c0 */, &quirk->mem,
> +                                &error_abort);
>  
>      QLIST_INSERT_HEAD(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks,
>                        quirk, next);
> @@ -1785,7 +1786,8 @@ static void vfio_vga_probe_nvidia_3d0_quirk(VFIOPCIDevice *vdev)
>      memory_region_init_io(&quirk->mem, OBJECT(vdev), &vfio_nvidia_3d0_quirk,
>                            quirk, "vfio-nvidia-3d0-quirk", 6);
>      memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,
> -                                quirk->data.base_offset, &quirk->mem);
> +                                quirk->data.base_offset, &quirk->mem,
> +                                &error_abort);
>  
>      QLIST_INSERT_HEAD(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks,
>                        quirk, next);
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 7a89081..9c95c74 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -1279,7 +1279,8 @@ static void virtio_pci_modern_region_map(VirtIOPCIProxy *proxy,
>  {
>      memory_region_add_subregion(&proxy->modern_bar,
>                                  region->offset,
> -                                &region->mr);
> +                                &region->mr,
> +                                &error_abort);
>  
>      cap->cfg_type = region->type;
>      cap->bar = proxy->modern_mem_bar;
> diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
> index 328d209..3da7ca4 100644
> --- a/hw/xtensa/sim.c
> +++ b/hw/xtensa/sim.c
> @@ -81,12 +81,13 @@ static void xtensa_sim_init(MachineState *machine)
>      ram = g_malloc(sizeof(*ram));
>      memory_region_init_ram(ram, NULL, "xtensa.sram", ram_size, &error_abort);
>      vmstate_register_ram_global(ram);
> -    memory_region_add_subregion(get_system_memory(), 0, ram);
> +    memory_region_add_subregion(get_system_memory(), 0, ram, &error_abort);
>  
>      rom = g_malloc(sizeof(*rom));
>      memory_region_init_ram(rom, NULL, "xtensa.rom", 0x1000, &error_abort);
>      vmstate_register_ram_global(rom);
> -    memory_region_add_subregion(get_system_memory(), 0xfe000000, rom);
> +    memory_region_add_subregion(get_system_memory(), 0xfe000000, rom,
> +                                &error_abort);
>  
>      if (kernel_filename) {
>          uint64_t elf_entry;
> diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
> index ab4d0e4..40bfb81 100644
> --- a/hw/xtensa/xtfpga.c
> +++ b/hw/xtensa/xtfpga.c
> @@ -115,7 +115,7 @@ static Lx60FpgaState *lx60_fpga_init(MemoryRegion *address_space,
>  
>      memory_region_init_io(&s->iomem, NULL, &lx60_fpga_ops, s,
>              "lx60.fpga", 0x10000);
> -    memory_region_add_subregion(address_space, base, &s->iomem);
> +    memory_region_add_subregion(address_space, base, &s->iomem, &error_abort);
>      lx60_fpga_reset(s);
>      qemu_register_reset(lx60_fpga_reset, s);
>      return s;
> @@ -138,14 +138,14 @@ static void lx60_net_init(MemoryRegion *address_space,
>      s = SYS_BUS_DEVICE(dev);
>      sysbus_connect_irq(s, 0, irq);
>      memory_region_add_subregion(address_space, base,
> -            sysbus_mmio_get_region(s, 0));
> +            sysbus_mmio_get_region(s, 0), &error_abort);
>      memory_region_add_subregion(address_space, descriptors,
> -            sysbus_mmio_get_region(s, 1));
> +            sysbus_mmio_get_region(s, 1), &error_abort);
>  
>      ram = g_malloc(sizeof(*ram));
>      memory_region_init_ram(ram, OBJECT(s), "open_eth.ram", 16384, &error_abort);
>      vmstate_register_ram_global(ram);
> -    memory_region_add_subregion(address_space, buffers, ram);
> +    memory_region_add_subregion(address_space, buffers, ram, &error_abort);
>  }
>  
>  static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
> @@ -225,12 +225,13 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
>      memory_region_init_ram(ram, NULL, "lx60.dram", machine->ram_size,
>                             &error_abort);
>      vmstate_register_ram_global(ram);
> -    memory_region_add_subregion(system_memory, 0, ram);
> +    memory_region_add_subregion(system_memory, 0, ram, &error_abort);
>  
>      system_io = g_malloc(sizeof(*system_io));
>      memory_region_init_io(system_io, NULL, &lx60_io_ops, NULL, "lx60.io",
>                            224 * 1024 * 1024);
> -    memory_region_add_subregion(system_memory, 0xf0000000, system_io);
> +    memory_region_add_subregion(system_memory, 0xf0000000, system_io,
> +                                &error_abort);
>      lx60_fpga_init(system_io, 0x0d020000);
>      if (nd_table[0].used) {
>          lx60_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000,
> @@ -277,7 +278,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
>          memory_region_init_ram(rom, NULL, "lx60.sram", board->sram_size,
>                                 &error_abort);
>          vmstate_register_ram_global(rom);
> -        memory_region_add_subregion(system_memory, 0xfe000000, rom);
> +        memory_region_add_subregion(system_memory, 0xfe000000, rom,
> +                                    &error_abort);
>  
>          if (kernel_cmdline) {
>              bp_size += get_tag_size(strlen(kernel_cmdline) + 1);
> @@ -377,7 +379,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
>                      board->flash_size - board->flash_boot_base < 0x02000000 ?
>                      board->flash_size - board->flash_boot_base : 0x02000000);
>              memory_region_add_subregion(system_memory, 0xfe000000,
> -                    flash_io);
> +                    flash_io, &error_abort);
>          }
>      }
>  }
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index b9e6112..ce0320a 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -928,7 +928,8 @@ void memory_region_del_eventfd(MemoryRegion *mr,
>   */
>  void memory_region_add_subregion(MemoryRegion *mr,
>                                   hwaddr offset,
> -                                 MemoryRegion *subregion);
> +                                 MemoryRegion *subregion,
> +                                 Error **errp);
>  /**
>   * memory_region_add_subregion_overlap: Add a subregion to a container
>   *                                      with overlap.
> diff --git a/ioport.c b/ioport.c
> index e39093e..8943e16 100644
> --- a/ioport.c
> +++ b/ioport.c
> @@ -257,7 +257,7 @@ static void portio_list_add_1(PortioList *piolist,
>          memory_region_set_flush_coalesced(&mrpio->mr);
>      }
>      memory_region_add_subregion(piolist->address_space,
> -                                start + off_low, &mrpio->mr);
> +                                start + off_low, &mrpio->mr, &error_abort);
>      piolist->regions[piolist->nr] = &mrpio->mr;
>      ++piolist->nr;
>  }
> diff --git a/memory.c b/memory.c
> index 4558d85..360a5b8 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1763,7 +1763,8 @@ done:
>  
>  static void memory_region_add_subregion_common(MemoryRegion *mr,
>                                                 hwaddr offset,
> -                                               MemoryRegion *subregion)
> +                                               MemoryRegion *subregion,
> +                                               Error **errp)
>  {
>      assert(!subregion->container);
>      subregion->container = mr;
> @@ -1781,11 +1782,11 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
>  
>  void memory_region_add_subregion(MemoryRegion *mr,
>                                   hwaddr offset,
> -                                 MemoryRegion *subregion)
> +                                 MemoryRegion *subregion, Error **errp)
>  {
>      subregion->may_overlap = false;
>      subregion->priority = 0;
> -    memory_region_add_subregion_common(mr, offset, subregion);
> +    memory_region_add_subregion_common(mr, offset, subregion, errp);
>  }
>  
>  void memory_region_add_subregion_overlap(MemoryRegion *mr,
> @@ -1795,7 +1796,7 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
>  {
>      subregion->may_overlap = true;
>      subregion->priority = priority;
> -    memory_region_add_subregion_common(mr, offset, subregion);
> +    memory_region_add_subregion_common(mr, offset, subregion, &error_abort);
>  }
>  
>  void memory_region_del_subregion(MemoryRegion *mr,
> diff --git a/numa.c b/numa.c
> index 3c80059..0ec9e58 100644
> --- a/numa.c
> +++ b/numa.c
> @@ -469,7 +469,7 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
>              exit(1);
>          }
>  
> -        memory_region_add_subregion(mr, addr, seg);
> +        memory_region_add_subregion(mr, addr, seg, &error_abort);
>          vmstate_register_ram_global(seg);
>          addr += size;
>      }
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08  9:46 ` [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting Igor Mammedov
  2015-07-08 11:03   ` Michael S. Tsirkin
@ 2015-07-08 11:09   ` Peter Maydell
  2015-07-08 14:58     ` Igor Mammedov
  1 sibling, 1 reply; 31+ messages in thread
From: Peter Maydell @ 2015-07-08 11:09 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: Paolo Bonzini, QEMU Developers, Michael S. Tsirkin

On 8 July 2015 at 10:46, Igor Mammedov <imammedo@redhat.com> wrote:
> extends memory_region_add_subregion() by adding Error**
> argument to allow t fail and return a error from it.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>  156 files changed, 619 insertions(+), 420 deletions(-)

This is a seriously invasive API change and I don't
really like it -- reconfiguring the memory region
hierarchy should not be an operation which can fail
(especially not just adding a subregion!)

-- PMM

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-08 10:01 ` [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Michael S. Tsirkin
@ 2015-07-08 11:41   ` Igor Mammedov
  2015-07-08 11:45     ` Michael S. Tsirkin
  2015-07-08 15:46   ` Igor Mammedov
  1 sibling, 1 reply; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08 11:41 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: pbonzini, qemu-devel

On Wed, 8 Jul 2015 13:01:05 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jul 08, 2015 at 11:46:40AM +0200, Igor Mammedov wrote:
> > Changelog:
> >  v2->v3:
> >    * fixed(work-arouned) unmapping issues,
> >      now memory subsytem keeps track of HVA mapped
> >      regions and doesn't allow to map a new region
> >      at address where previos has benn mapped until
> >      previous region is gone
> >    * fixed offset calculations in memory_region_find_hva_range()
> >      in 2/8
> >    * redone MemorySection folding into HVA range for VHOST,
> >      now compacted memory map is temporary and passed only to vhost
> >      backend and doesn't touch original memory map used by QEMU
> >  v1->v2:
> >    * take into account Paolo's review comments
> >      * do not overload ram_addr
> >      * ifdef linux specific code
> >    * reseve HVA using API from exec.c instead of calling
> >      mmap() dircely from memory.c
> >    * support unmapping of HVA remapped region
> > 
> > When more than ~50 pc-dimm devices are hotplugged with
> > vhost enabled, QEMU will assert in vhost vhost_commit()
> > due to backend refusing to accept too many memory ranges.
> > 
> > Series introduces Reserved HVA MemoryRegion container
> > where to all hotplugged memory is remapped and passes
> > the single container range to vhost instead of multiple
> > memory ranges for each hotlugged pc-dimm device.
> 
> Did not review yet, two procedural comments:
> 
> - this fixes qemu on current kernels, so it's a bugfix
it's easier/safer to patch current kernels with much simpler
fix on kernel side.
I'd call this series a workaround to overcome current vhost
limitation, which hacks around QEMU's memory layer to satisfy
broken vhost.
For my point of view HVA hack is worth only if
we convert all RAM including initial RAM and replace lookup
in vhost region mapping with a simple computation using single
HVA range.
So far 'cure' in QEMU is much worse than rising limit on vhost
backend side.

 
> - this changes the semantics of memory hot unplug slightly
>   so I think it's important to merge in 2.4 before we
>   release qemu with memory hot unplug, this way we
>   won't have to maintain old semantics forever
It changes memory hotplug semantics as following:
  * hotplug at previously used address could fail gracefully
    if previous mapping is still in use
  * user MUST remove corresponding backend after removing
    pc-dimm device
Above limitations apply only if vhost is used, but pointless
in all other cases so I'm not sure that we should enforce
them on vhost-less setups.

As additional issue:
deleting backend doesn't actually frees memory since it's
just mmap(NORESERVE) over allocated region. It's possible
to do madvise(MADV_DONTNEED) on area but it doesn't guaranty
that kernel will free memory. So all these mmap/remap
tricks could screw up mgmt tools if they try to limit memory
consumed by QEMU.

series is not tested wrt cross-version migration.

> 
> 
> > It's an alternative approach to increasing backend supported
> > memory regions limit. 
> > 
> > git branch for testing:
> >   https://github.com/imammedo/qemu/commits/vhost_one_hp_range_v3
> > 
> > Igor Mammedov (8):
> >   memory: get rid of memory_region_destructor_ram_from_ptr()
> >   memory: introduce MemoryRegion container with reserved HVA range
> >   pc: reserve hotpluggable memory range with
> >     memory_region_init_hva_range()
> >   pc: fix QEMU crashing when more than ~50 memory hotplugged
> >   exec: make sure that RAMBlock descriptor won't be leaked
> >   exec: add qemu_ram_unmap_hva() API for unmapping memory from HVA area
> >   memory: extend memory_region_add_subregion() to support error
> >     reporting
> >   memory: add support for deleting HVA mapped MemoryRegion
> > 
> >  exec.c                                   |  71 ++++++++++++-------
> >  hw/acpi/core.c                           |   6 +-
> >  hw/acpi/cpu_hotplug.c                    |   2 +-
> >  hw/acpi/ich9.c                           |   8 ++-
> >  hw/acpi/memory_hotplug.c                 |   3 +-
> >  hw/acpi/pcihp.c                          |   3 +-
> >  hw/acpi/piix4.c                          |   6 +-
> >  hw/alpha/typhoon.c                       |  16 ++---
> >  hw/arm/armv7m.c                          |   2 +-
> >  hw/arm/cubieboard.c                      |   2 +-
> >  hw/arm/digic_boards.c                    |   2 +-
> >  hw/arm/exynos4210.c                      |  12 ++--
> >  hw/arm/highbank.c                        |   4 +-
> >  hw/arm/integratorcp.c                    |   5 +-
> >  hw/arm/kzm.c                             |   9 ++-
> >  hw/arm/mainstone.c                       |   2 +-
> >  hw/arm/musicpal.c                        |   5 +-
> >  hw/arm/omap1.c                           |  59 +++++++++-------
> >  hw/arm/omap2.c                           |   8 ++-
> >  hw/arm/omap_sx1.c                        |  19 +++--
> >  hw/arm/palm.c                            |  14 ++--
> >  hw/arm/pxa2xx.c                          |  30 +++++---
> >  hw/arm/realview.c                        |   8 +--
> >  hw/arm/spitz.c                           |   2 +-
> >  hw/arm/stellaris.c                       |   7 +-
> >  hw/arm/stm32f205_soc.c                   |   8 ++-
> >  hw/arm/strongarm.c                       |   2 +-
> >  hw/arm/tosa.c                            |   2 +-
> >  hw/arm/versatilepb.c                     |   2 +-
> >  hw/arm/vexpress.c                        |  15 ++--
> >  hw/arm/virt.c                            |  12 ++--
> >  hw/arm/xilinx_zynq.c                     |   5 +-
> >  hw/arm/xlnx-ep108.c                      |   3 +-
> >  hw/arm/xlnx-zynqmp.c                     |   3 +-
> >  hw/block/onenand.c                       |   2 +-
> >  hw/block/pflash_cfi02.c                  |   3 +-
> >  hw/char/debugcon.c                       |   2 +-
> >  hw/char/mcf_uart.c                       |   2 +-
> >  hw/char/omap_uart.c                      |   2 +-
> >  hw/char/parallel.c                       |   2 +-
> >  hw/char/serial-pci.c                     |   2 +-
> >  hw/char/serial.c                         |   4 +-
> >  hw/char/sh_serial.c                      |   6 +-
> >  hw/core/platform-bus.c                   |   2 +-
> >  hw/core/sysbus.c                         |   4 +-
> >  hw/cpu/a15mpcore.c                       |   6 +-
> >  hw/cpu/a9mpcore.c                        |  18 +++--
> >  hw/cpu/arm11mpcore.c                     |  15 ++--
> >  hw/cris/axis_dev88.c                     |  10 +--
> >  hw/display/cirrus_vga.c                  |  11 +--
> >  hw/display/omap_dss.c                    |   2 +-
> >  hw/display/omap_lcdc.c                   |   2 +-
> >  hw/display/pxa2xx_lcd.c                  |   2 +-
> >  hw/display/sm501.c                       |   9 +--
> >  hw/display/tc6393xb.c                    |   5 +-
> >  hw/display/vga-isa-mm.c                  |   6 +-
> >  hw/display/vga-pci.c                     |   6 +-
> >  hw/display/vga.c                         |   3 +-
> >  hw/dma/etraxfs_dma.c                     |   3 +-
> >  hw/dma/i8257.c                           |   5 +-
> >  hw/dma/omap_dma.c                        |   4 +-
> >  hw/dma/rc4030.c                          |   4 +-
> >  hw/i386/kvm/pci-assign.c                 |   6 +-
> >  hw/i386/pc.c                             |  16 +++--
> >  hw/i386/pc_sysfw.c                       |   2 +-
> >  hw/ide/cmd646.c                          |   6 +-
> >  hw/ide/piix.c                            |   6 +-
> >  hw/ide/via.c                             |   6 +-
> >  hw/input/pxa2xx_keypad.c                 |   2 +-
> >  hw/intc/apic_common.c                    |   3 +-
> >  hw/intc/armv7m_nvic.c                    |   5 +-
> >  hw/intc/exynos4210_gic.c                 |   6 +-
> >  hw/intc/openpic.c                        |   2 +-
> >  hw/intc/realview_gic.c                   |   6 +-
> >  hw/intc/sh_intc.c                        |   6 +-
> >  hw/isa/apm.c                             |   2 +-
> >  hw/isa/isa-bus.c                         |   3 +-
> >  hw/isa/vt82c686.c                        |   7 +-
> >  hw/lm32/lm32_boards.c                    |   6 +-
> >  hw/lm32/milkymist.c                      |   3 +-
> >  hw/m68k/an5206.c                         |   5 +-
> >  hw/m68k/dummy_m68k.c                     |   2 +-
> >  hw/m68k/mcf5206.c                        |   2 +-
> >  hw/m68k/mcf5208.c                        |  10 +--
> >  hw/m68k/mcf_intc.c                       |   2 +-
> >  hw/mem/pc-dimm.c                         |   6 +-
> >  hw/microblaze/petalogix_ml605_mmu.c      |   6 +-
> >  hw/microblaze/petalogix_s3adsp1800_mmu.c |   5 +-
> >  hw/mips/gt64xxx_pci.c                    |   9 +--
> >  hw/mips/mips_fulong2e.c                  |   5 +-
> >  hw/mips/mips_jazz.c                      |  30 +++++---
> >  hw/mips/mips_malta.c                     |  17 +++--
> >  hw/mips/mips_mipssim.c                   |  11 +--
> >  hw/mips/mips_r4k.c                       |  14 ++--
> >  hw/misc/debugexit.c                      |   2 +-
> >  hw/misc/ivshmem.c                        |   4 +-
> >  hw/misc/macio/macio.c                    |  24 ++++---
> >  hw/misc/omap_gpmc.c                      |   7 +-
> >  hw/misc/omap_l4.c                        |   3 +-
> >  hw/misc/omap_sdrc.c                      |   2 +-
> >  hw/misc/pc-testdev.c                     |  11 +--
> >  hw/moxie/moxiesim.c                      |   4 +-
> >  hw/net/fsl_etsec/etsec.c                 |   3 +-
> >  hw/net/mcf_fec.c                         |   2 +-
> >  hw/openrisc/openrisc_sim.c               |   6 +-
> >  hw/pci-host/apb.c                        |   3 +-
> >  hw/pci-host/grackle.c                    |   2 +-
> >  hw/pci-host/piix.c                       |   3 +-
> >  hw/pci-host/ppce500.c                    |  13 ++--
> >  hw/pci-host/prep.c                       |  24 ++++---
> >  hw/pci-host/q35.c                        |   8 ++-
> >  hw/pci-host/uninorth.c                   |   4 +-
> >  hw/pci/msix.c                            |   6 +-
> >  hw/pci/pcie_host.c                       |   3 +-
> >  hw/pci/shpc.c                            |   2 +-
> >  hw/pcmcia/pxa2xx.c                       |   6 +-
> >  hw/ppc/e500.c                            |  14 ++--
> >  hw/ppc/mac_newworld.c                    |  14 ++--
> >  hw/ppc/mac_oldworld.c                    |   6 +-
> >  hw/ppc/ppc405_boards.c                   |  12 ++--
> >  hw/ppc/ppc405_uc.c                       |  16 +++--
> >  hw/ppc/ppc440_bamboo.c                   |   3 +-
> >  hw/ppc/ppc4xx_devs.c                     |   4 +-
> >  hw/ppc/ppc4xx_pci.c                      |   9 ++-
> >  hw/ppc/prep.c                            |   4 +-
> >  hw/ppc/spapr.c                           |   4 +-
> >  hw/ppc/spapr_pci.c                       |   8 +--
> >  hw/ppc/spapr_pci_vfio.c                  |   2 +-
> >  hw/ppc/virtex_ml507.c                    |   3 +-
> >  hw/s390x/s390-virtio-ccw.c               |   2 +-
> >  hw/s390x/s390-virtio.c                   |   2 +-
> >  hw/s390x/sclp.c                          |   3 +-
> >  hw/sd/omap_mmc.c                         |   2 +-
> >  hw/sd/pxa2xx_mmci.c                      |   2 +-
> >  hw/sh4/r2d.c                             |   5 +-
> >  hw/sh4/sh7750.c                          |  21 ++++--
> >  hw/sh4/sh_pci.c                          |   6 +-
> >  hw/sh4/shix.c                            |   6 +-
> >  hw/sparc/leon3.c                         |   6 +-
> >  hw/sparc64/sun4u.c                       |   2 +-
> >  hw/timer/m48t59.c                        |   3 +-
> >  hw/timer/sh_timer.c                      |   6 +-
> >  hw/tpm/tpm_tis.c                         |   2 +-
> >  hw/tricore/tricore_testboard.c           |  12 ++--
> >  hw/unicore32/puv3.c                      |   6 +-
> >  hw/usb/hcd-ehci-sysbus.c                 |   2 +-
> >  hw/usb/hcd-ehci.c                        |   8 ++-
> >  hw/usb/hcd-xhci.c                        |  15 ++--
> >  hw/vfio/common.c                         |   2 +-
> >  hw/vfio/pci.c                            |   6 +-
> >  hw/virtio/vhost.c                        |  47 +++++++++++-
> >  hw/virtio/virtio-pci.c                   |   3 +-
> >  hw/xtensa/sim.c                          |   5 +-
> >  hw/xtensa/xtfpga.c                       |  18 ++---
> >  include/exec/cpu-common.h                |   3 +
> >  include/exec/memory.h                    |  49 ++++++++++++-
> >  include/exec/ram_addr.h                  |   1 -
> >  include/hw/virtio/vhost.h                |   1 +
> >  ioport.c                                 |   2 +-
> >  memory.c                                 | 118 ++++++++++++++++++++++++++++---
> >  numa.c                                   |   2 +-
> >  161 files changed, 867 insertions(+), 458 deletions(-)
> > 
> > -- 
> > 1.8.3.1

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-08 11:41   ` Igor Mammedov
@ 2015-07-08 11:45     ` Michael S. Tsirkin
  0 siblings, 0 replies; 31+ messages in thread
From: Michael S. Tsirkin @ 2015-07-08 11:45 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, qemu-devel

On Wed, Jul 08, 2015 at 01:41:16PM +0200, Igor Mammedov wrote:
> As additional issue:
> deleting backend doesn't actually frees memory since it's
> just mmap(NORESERVE) over allocated region. It's possible
> to do madvise(MADV_DONTNEED) on area but it doesn't guaranty
> that kernel will free memory.

munmap does not guarantee that either.

> So all these mmap/remap
> tricks could screw up mgmt tools if they try to limit memory
> consumed by QEMU.

It's likely easier to manage if virtual memory
usage does not jump up and down randomly.
 
> series is not tested wrt cross-version migration.

Testing is always good but I don't see anything
touching migration here.

-- 
MST

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 8/8] memory: add support for deleting HVA mapped MemoryRegion
  2015-07-08  9:58   ` Michael S. Tsirkin
@ 2015-07-08 14:43     ` Igor Mammedov
  2015-07-08 14:50       ` Michael S. Tsirkin
  0 siblings, 1 reply; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08 14:43 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: pbonzini, qemu-devel

On Wed, 8 Jul 2015 12:58:55 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jul 08, 2015 at 11:46:48AM +0200, Igor Mammedov wrote:
> > Although memory_region_del_subregion() removes MemoryRegion
> > from current address space, it's possible that it's still
> > in use/referenced until old address space view is destroyed.
> > That doesn't allow to unmap it from HVA region at the time
> > of memory_region_del_subregion().
> > As a solution track HVA mapped MemoryRegions in a list and
> > don't allow to map another MemoryRegion at the same address
> > until respective MemoryRegion is destroyed, delaying unmapping
> > from HVA range to the time MemoryRegion destructor is called.
> > 
> > In memory hotplug terms it would mean that user should delete
> > corresponding backend along with pc-dimm device:
> >  device_del dimm1
> >  object_del dimm1_backend_memdev
> > after that dimm1_backend_memdev's MemoryRegion will be destroyed
> > once all accesses to it are gone and old flatview is destroyed as
> > well.
> > As result it's possible that a following "device_add pc-dimm" at
> > the same address may fail due to old mapping is still being present,
> 
> 
> s/is still/still/
fixed

> 
> > hence add error argument to memory_region_add_subregion() API
> > so it could report error and hotplug could be cancelled gracefully.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> The commit log seems a bit confusing.
> API was added in previous patch, and this one actually
> uses it.
previous patch added qemu_ram_* API utilities at exec.c
but this patch adds memory_region_* API changes that would allow
to delete HVA mapped region safely.

Is there any suggestion how to make commit message less confusing.

> 
> > ---
> >  hw/mem/pc-dimm.c      |  6 +++++-
> >  include/exec/memory.h |  2 ++
> >  memory.c              | 55
> > +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files
> > changed, 62 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
> > index 8cc9118..d17c22f 100644
> > --- a/hw/mem/pc-dimm.c
> > +++ b/hw/mem/pc-dimm.c
> > @@ -95,7 +95,11 @@ void pc_dimm_memory_plug(DeviceState *dev,
> > MemoryHotplugState *hpms, goto out;
> >      }
> >  
> > -    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr,
> > &error_abort);
> > +    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr,
> > &local_err);
> > +    if (local_err) {
> > +        goto out;
> > +    }
> > +
> >      vmstate_register_ram(mr, dev);
> >      numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
> >  
> > diff --git a/include/exec/memory.h b/include/exec/memory.h
> > index ce0320a..d9c53f9 100644
> > --- a/include/exec/memory.h
> > +++ b/include/exec/memory.h
> > @@ -174,6 +174,7 @@ struct MemoryRegion {
> >      bool romd_mode;
> >      bool ram;
> >      void *rsvd_hva;
> > +    bool hva_mapped;
> >      bool skip_dump;
> >      bool readonly; /* For RAM regions */
> >      bool enabled;
> > @@ -188,6 +189,7 @@ struct MemoryRegion {
> >      QTAILQ_HEAD(subregions, MemoryRegion) subregions;
> >      QTAILQ_ENTRY(MemoryRegion) subregions_link;
> >      QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
> > +    QTAILQ_ENTRY(MemoryRegion) hva_link;
> >      const char *name;
> >      uint8_t dirty_log_mask;
> >      unsigned ioeventfd_nb;
> > diff --git a/memory.c b/memory.c
> > index 360a5b8..e3c1b36 100644
> > --- a/memory.c
> > +++ b/memory.c
> > @@ -34,6 +34,7 @@ static unsigned memory_region_transaction_depth;
> >  static bool memory_region_update_pending;
> >  static bool ioeventfd_update_pending;
> >  static bool global_dirty_log = false;
> > +static QemuMutex hva_lock;
> >  
> >  static QTAILQ_HEAD(memory_listeners, MemoryListener)
> > memory_listeners = QTAILQ_HEAD_INITIALIZER(memory_listeners);
> > @@ -1761,6 +1762,24 @@ done:
> >      memory_region_transaction_commit();
> >  }
> >  
> > +static QTAILQ_HEAD(, MemoryRegion) hva_mapped_head =
> > +    QTAILQ_HEAD_INITIALIZER(hva_mapped_head);
> > +
> > +static void memory_region_destructor_hva_ram(MemoryRegion *mr)
> > +{
> > +    MemoryRegion *h, *tmp;
> > +
> > +    qemu_mutex_lock(&hva_lock);
> > +    qemu_ram_unmap_hva(mr->ram_addr);
> > +    memory_region_destructor_ram(mr);
> > +    QTAILQ_FOREACH_SAFE(h, &hva_mapped_head, hva_link, tmp) {
> > +        if (mr == h) {
> > +            QTAILQ_REMOVE(&hva_mapped_head, h, hva_link);
> > +        }
> > +    }
> > +    qemu_mutex_unlock(&hva_lock);
> > +}
> > +
> >  static void memory_region_add_subregion_common(MemoryRegion *mr,
> >                                                 hwaddr offset,
> >                                                 MemoryRegion
> > *subregion, @@ -1772,8 +1791,43 @@ static void
> > memory_region_add_subregion_common(MemoryRegion *mr, 
> >      if (subregion->ram) {
> >          if (mr->rsvd_hva) {
> > +            MemoryRegion *h, *tmp;
> > +            Int128 e, oe;
> > +
> > +            assert(!subregion->hva_mapped);
> > +            qemu_mutex_lock(&hva_lock);
> > +
> > +            QTAILQ_FOREACH_SAFE(h, &hva_mapped_head, hva_link,
> > tmp) {
> > +                if (subregion == h) {
> > +                    error_setg(errp, "HVA mapped memory region
> > '%s' is not "
> > +                               "reusable, use a new one instead",
> > +                               subregion->name);
> > +                    qemu_mutex_unlock(&hva_lock);
> > +                    return;
> > +                }
> > +
> > +                e = int128_add(int128_make64(h->addr),
> > +
> > int128_make64(memory_region_size(h)));
> > +                oe = int128_add(int128_make64(offset),
> > +
> > int128_make64(memory_region_size(subregion)));
> > +                if (offset >= h->addr && int128_le(oe, e)) {
> > +                    MemoryRegionSection rsvd_hva;
> > +                    rsvd_hva = memory_region_find_hva_range(mr);
> > +                    error_setg(errp, "memory at 0x%" PRIx64 " is
> > still in use"
> > +                               "by HVA mapped region: %s",
> > +
> > rsvd_hva.offset_within_address_space + offset,
> > +                               h->name);
> > +                    qemu_mutex_unlock(&hva_lock);
> > +                    return;
> > +                }
> > +            }
> > +
> > +            QTAILQ_INSERT_TAIL(&hva_mapped_head, subregion,
> > hva_link);
> > +            subregion->destructor =
> > memory_region_destructor_hva_ram;
> > +            subregion->hva_mapped = true;
> >              qemu_ram_remap_hva(subregion->ram_addr,
> >                  memory_region_get_ram_ptr(mr) + subregion->addr);
> > +            qemu_mutex_unlock(&hva_lock);
> >          }
> >      }
> >  
> > @@ -2288,6 +2342,7 @@ static const TypeInfo memory_region_info = {
> >  static void memory_register_types(void)
> >  {
> >      type_register_static(&memory_region_info);
> > +    qemu_mutex_init(&hva_lock);
> >  }
> >  
> >  type_init(memory_register_types)
> > -- 
> > 1.8.3.1
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 8/8] memory: add support for deleting HVA mapped MemoryRegion
  2015-07-08 14:43     ` Igor Mammedov
@ 2015-07-08 14:50       ` Michael S. Tsirkin
  0 siblings, 0 replies; 31+ messages in thread
From: Michael S. Tsirkin @ 2015-07-08 14:50 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, qemu-devel

On Wed, Jul 08, 2015 at 04:43:55PM +0200, Igor Mammedov wrote:
> On Wed, 8 Jul 2015 12:58:55 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Jul 08, 2015 at 11:46:48AM +0200, Igor Mammedov wrote:
> > > Although memory_region_del_subregion() removes MemoryRegion
> > > from current address space, it's possible that it's still
> > > in use/referenced until old address space view is destroyed.
> > > That doesn't allow to unmap it from HVA region at the time
> > > of memory_region_del_subregion().
> > > As a solution track HVA mapped MemoryRegions in a list and
> > > don't allow to map another MemoryRegion at the same address
> > > until respective MemoryRegion is destroyed, delaying unmapping
> > > from HVA range to the time MemoryRegion destructor is called.
> > > 
> > > In memory hotplug terms it would mean that user should delete
> > > corresponding backend along with pc-dimm device:
> > >  device_del dimm1
> > >  object_del dimm1_backend_memdev
> > > after that dimm1_backend_memdev's MemoryRegion will be destroyed
> > > once all accesses to it are gone and old flatview is destroyed as
> > > well.
> > > As result it's possible that a following "device_add pc-dimm" at
> > > the same address may fail due to old mapping is still being present,
> > 
> > 
> > s/is still/still/
> fixed
> 
> > 
> > > hence add error argument to memory_region_add_subregion() API
> > > so it could report error and hotplug could be cancelled gracefully.
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > 
> > The commit log seems a bit confusing.
> > API was added in previous patch, and this one actually
> > uses it.
> previous patch added qemu_ram_* API utilities at exec.c
> but this patch adds memory_region_* API changes that would allow
> to delete HVA mapped region safely.

I see two changes in memory.h, all private fields.

> Is there any suggestion how to make commit message less confusing.


Just make it match what the patch does.

> > > diff --git a/include/exec/memory.h b/include/exec/memory.h
> > > index ce0320a..d9c53f9 100644
> > > --- a/include/exec/memory.h
> > > +++ b/include/exec/memory.h
> > > @@ -174,6 +174,7 @@ struct MemoryRegion {
> > >      bool romd_mode;
> > >      bool ram;
> > >      void *rsvd_hva;
> > > +    bool hva_mapped;
> > >      bool skip_dump;
> > >      bool readonly; /* For RAM regions */
> > >      bool enabled;
> > > @@ -188,6 +189,7 @@ struct MemoryRegion {
> > >      QTAILQ_HEAD(subregions, MemoryRegion) subregions;
> > >      QTAILQ_ENTRY(MemoryRegion) subregions_link;
> > >      QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
> > > +    QTAILQ_ENTRY(MemoryRegion) hva_link;
> > >      const char *name;
> > >      uint8_t dirty_log_mask;
> > >      unsigned ioeventfd_nb;

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08 11:09   ` Peter Maydell
@ 2015-07-08 14:58     ` Igor Mammedov
  2015-07-08 17:30       ` Michael S. Tsirkin
  2015-07-08 17:42       ` Paolo Bonzini
  0 siblings, 2 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08 14:58 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, QEMU Developers, Michael S. Tsirkin

On Wed, 8 Jul 2015 12:09:10 +0100
Peter Maydell <peter.maydell@linaro.org> wrote:

> On 8 July 2015 at 10:46, Igor Mammedov <imammedo@redhat.com> wrote:
> > extends memory_region_add_subregion() by adding Error**
> > argument to allow t fail and return a error from it.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> >  156 files changed, 619 insertions(+), 420 deletions(-)
> 
> This is a seriously invasive API change and I don't
> really like it -- reconfiguring the memory region
> hierarchy should not be an operation which can fail
> (especially not just adding a subregion!)
> 
> -- PMM
> 

I'll drop this patch in favor of dedicated
memory_region_add_subregion_to_hva() API that can fail and return error.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-08 10:01 ` [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Michael S. Tsirkin
  2015-07-08 11:41   ` Igor Mammedov
@ 2015-07-08 15:46   ` Igor Mammedov
  2015-07-09 17:04     ` Andrey Korolyov
  1 sibling, 1 reply; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08 15:46 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: pbonzini, pkrempa, andrey, qemu-devel

On Wed, 8 Jul 2015 13:01:05 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

[...]
> - this fixes qemu on current kernels, so it's a bugfix
> 
> - this changes the semantics of memory hot unplug slightly
>   so I think it's important to merge in 2.4 before we
>   release qemu with memory hot unplug, this way we
>   won't have to maintain old semantics forever
concerning semantic change, I've just chatted with Peter
who implemented libvirt side of the memory hotplug stack.
And it's not a problem for libvirt since it always does
unplug dimm -> remove backend sequence. 


> 
> > It's an alternative approach to increasing backend supported
> > memory regions limit. 
> > 
> > git branch for testing:
> >   https://github.com/imammedo/qemu/commits/vhost_one_hp_range_v3
> > 
> > Igor Mammedov (8):
> >   memory: get rid of memory_region_destructor_ram_from_ptr()
> >   memory: introduce MemoryRegion container with reserved HVA range
> >   pc: reserve hotpluggable memory range with
> >     memory_region_init_hva_range()
> >   pc: fix QEMU crashing when more than ~50 memory hotplugged
> >   exec: make sure that RAMBlock descriptor won't be leaked
> >   exec: add qemu_ram_unmap_hva() API for unmapping memory from HVA
> > area memory: extend memory_region_add_subregion() to support error
> >     reporting
> >   memory: add support for deleting HVA mapped MemoryRegion
> > 
> >  exec.c                                   |  71 ++++++++++++-------
> >  hw/acpi/core.c                           |   6 +-
> >  hw/acpi/cpu_hotplug.c                    |   2 +-
> >  hw/acpi/ich9.c                           |   8 ++-
> >  hw/acpi/memory_hotplug.c                 |   3 +-
> >  hw/acpi/pcihp.c                          |   3 +-
> >  hw/acpi/piix4.c                          |   6 +-
> >  hw/alpha/typhoon.c                       |  16 ++---
> >  hw/arm/armv7m.c                          |   2 +-
> >  hw/arm/cubieboard.c                      |   2 +-
> >  hw/arm/digic_boards.c                    |   2 +-
> >  hw/arm/exynos4210.c                      |  12 ++--
> >  hw/arm/highbank.c                        |   4 +-
> >  hw/arm/integratorcp.c                    |   5 +-
> >  hw/arm/kzm.c                             |   9 ++-
> >  hw/arm/mainstone.c                       |   2 +-
> >  hw/arm/musicpal.c                        |   5 +-
> >  hw/arm/omap1.c                           |  59 +++++++++-------
> >  hw/arm/omap2.c                           |   8 ++-
> >  hw/arm/omap_sx1.c                        |  19 +++--
> >  hw/arm/palm.c                            |  14 ++--
> >  hw/arm/pxa2xx.c                          |  30 +++++---
> >  hw/arm/realview.c                        |   8 +--
> >  hw/arm/spitz.c                           |   2 +-
> >  hw/arm/stellaris.c                       |   7 +-
> >  hw/arm/stm32f205_soc.c                   |   8 ++-
> >  hw/arm/strongarm.c                       |   2 +-
> >  hw/arm/tosa.c                            |   2 +-
> >  hw/arm/versatilepb.c                     |   2 +-
> >  hw/arm/vexpress.c                        |  15 ++--
> >  hw/arm/virt.c                            |  12 ++--
> >  hw/arm/xilinx_zynq.c                     |   5 +-
> >  hw/arm/xlnx-ep108.c                      |   3 +-
> >  hw/arm/xlnx-zynqmp.c                     |   3 +-
> >  hw/block/onenand.c                       |   2 +-
> >  hw/block/pflash_cfi02.c                  |   3 +-
> >  hw/char/debugcon.c                       |   2 +-
> >  hw/char/mcf_uart.c                       |   2 +-
> >  hw/char/omap_uart.c                      |   2 +-
> >  hw/char/parallel.c                       |   2 +-
> >  hw/char/serial-pci.c                     |   2 +-
> >  hw/char/serial.c                         |   4 +-
> >  hw/char/sh_serial.c                      |   6 +-
> >  hw/core/platform-bus.c                   |   2 +-
> >  hw/core/sysbus.c                         |   4 +-
> >  hw/cpu/a15mpcore.c                       |   6 +-
> >  hw/cpu/a9mpcore.c                        |  18 +++--
> >  hw/cpu/arm11mpcore.c                     |  15 ++--
> >  hw/cris/axis_dev88.c                     |  10 +--
> >  hw/display/cirrus_vga.c                  |  11 +--
> >  hw/display/omap_dss.c                    |   2 +-
> >  hw/display/omap_lcdc.c                   |   2 +-
> >  hw/display/pxa2xx_lcd.c                  |   2 +-
> >  hw/display/sm501.c                       |   9 +--
> >  hw/display/tc6393xb.c                    |   5 +-
> >  hw/display/vga-isa-mm.c                  |   6 +-
> >  hw/display/vga-pci.c                     |   6 +-
> >  hw/display/vga.c                         |   3 +-
> >  hw/dma/etraxfs_dma.c                     |   3 +-
> >  hw/dma/i8257.c                           |   5 +-
> >  hw/dma/omap_dma.c                        |   4 +-
> >  hw/dma/rc4030.c                          |   4 +-
> >  hw/i386/kvm/pci-assign.c                 |   6 +-
> >  hw/i386/pc.c                             |  16 +++--
> >  hw/i386/pc_sysfw.c                       |   2 +-
> >  hw/ide/cmd646.c                          |   6 +-
> >  hw/ide/piix.c                            |   6 +-
> >  hw/ide/via.c                             |   6 +-
> >  hw/input/pxa2xx_keypad.c                 |   2 +-
> >  hw/intc/apic_common.c                    |   3 +-
> >  hw/intc/armv7m_nvic.c                    |   5 +-
> >  hw/intc/exynos4210_gic.c                 |   6 +-
> >  hw/intc/openpic.c                        |   2 +-
> >  hw/intc/realview_gic.c                   |   6 +-
> >  hw/intc/sh_intc.c                        |   6 +-
> >  hw/isa/apm.c                             |   2 +-
> >  hw/isa/isa-bus.c                         |   3 +-
> >  hw/isa/vt82c686.c                        |   7 +-
> >  hw/lm32/lm32_boards.c                    |   6 +-
> >  hw/lm32/milkymist.c                      |   3 +-
> >  hw/m68k/an5206.c                         |   5 +-
> >  hw/m68k/dummy_m68k.c                     |   2 +-
> >  hw/m68k/mcf5206.c                        |   2 +-
> >  hw/m68k/mcf5208.c                        |  10 +--
> >  hw/m68k/mcf_intc.c                       |   2 +-
> >  hw/mem/pc-dimm.c                         |   6 +-
> >  hw/microblaze/petalogix_ml605_mmu.c      |   6 +-
> >  hw/microblaze/petalogix_s3adsp1800_mmu.c |   5 +-
> >  hw/mips/gt64xxx_pci.c                    |   9 +--
> >  hw/mips/mips_fulong2e.c                  |   5 +-
> >  hw/mips/mips_jazz.c                      |  30 +++++---
> >  hw/mips/mips_malta.c                     |  17 +++--
> >  hw/mips/mips_mipssim.c                   |  11 +--
> >  hw/mips/mips_r4k.c                       |  14 ++--
> >  hw/misc/debugexit.c                      |   2 +-
> >  hw/misc/ivshmem.c                        |   4 +-
> >  hw/misc/macio/macio.c                    |  24 ++++---
> >  hw/misc/omap_gpmc.c                      |   7 +-
> >  hw/misc/omap_l4.c                        |   3 +-
> >  hw/misc/omap_sdrc.c                      |   2 +-
> >  hw/misc/pc-testdev.c                     |  11 +--
> >  hw/moxie/moxiesim.c                      |   4 +-
> >  hw/net/fsl_etsec/etsec.c                 |   3 +-
> >  hw/net/mcf_fec.c                         |   2 +-
> >  hw/openrisc/openrisc_sim.c               |   6 +-
> >  hw/pci-host/apb.c                        |   3 +-
> >  hw/pci-host/grackle.c                    |   2 +-
> >  hw/pci-host/piix.c                       |   3 +-
> >  hw/pci-host/ppce500.c                    |  13 ++--
> >  hw/pci-host/prep.c                       |  24 ++++---
> >  hw/pci-host/q35.c                        |   8 ++-
> >  hw/pci-host/uninorth.c                   |   4 +-
> >  hw/pci/msix.c                            |   6 +-
> >  hw/pci/pcie_host.c                       |   3 +-
> >  hw/pci/shpc.c                            |   2 +-
> >  hw/pcmcia/pxa2xx.c                       |   6 +-
> >  hw/ppc/e500.c                            |  14 ++--
> >  hw/ppc/mac_newworld.c                    |  14 ++--
> >  hw/ppc/mac_oldworld.c                    |   6 +-
> >  hw/ppc/ppc405_boards.c                   |  12 ++--
> >  hw/ppc/ppc405_uc.c                       |  16 +++--
> >  hw/ppc/ppc440_bamboo.c                   |   3 +-
> >  hw/ppc/ppc4xx_devs.c                     |   4 +-
> >  hw/ppc/ppc4xx_pci.c                      |   9 ++-
> >  hw/ppc/prep.c                            |   4 +-
> >  hw/ppc/spapr.c                           |   4 +-
> >  hw/ppc/spapr_pci.c                       |   8 +--
> >  hw/ppc/spapr_pci_vfio.c                  |   2 +-
> >  hw/ppc/virtex_ml507.c                    |   3 +-
> >  hw/s390x/s390-virtio-ccw.c               |   2 +-
> >  hw/s390x/s390-virtio.c                   |   2 +-
> >  hw/s390x/sclp.c                          |   3 +-
> >  hw/sd/omap_mmc.c                         |   2 +-
> >  hw/sd/pxa2xx_mmci.c                      |   2 +-
> >  hw/sh4/r2d.c                             |   5 +-
> >  hw/sh4/sh7750.c                          |  21 ++++--
> >  hw/sh4/sh_pci.c                          |   6 +-
> >  hw/sh4/shix.c                            |   6 +-
> >  hw/sparc/leon3.c                         |   6 +-
> >  hw/sparc64/sun4u.c                       |   2 +-
> >  hw/timer/m48t59.c                        |   3 +-
> >  hw/timer/sh_timer.c                      |   6 +-
> >  hw/tpm/tpm_tis.c                         |   2 +-
> >  hw/tricore/tricore_testboard.c           |  12 ++--
> >  hw/unicore32/puv3.c                      |   6 +-
> >  hw/usb/hcd-ehci-sysbus.c                 |   2 +-
> >  hw/usb/hcd-ehci.c                        |   8 ++-
> >  hw/usb/hcd-xhci.c                        |  15 ++--
> >  hw/vfio/common.c                         |   2 +-
> >  hw/vfio/pci.c                            |   6 +-
> >  hw/virtio/vhost.c                        |  47 +++++++++++-
> >  hw/virtio/virtio-pci.c                   |   3 +-
> >  hw/xtensa/sim.c                          |   5 +-
> >  hw/xtensa/xtfpga.c                       |  18 ++---
> >  include/exec/cpu-common.h                |   3 +
> >  include/exec/memory.h                    |  49 ++++++++++++-
> >  include/exec/ram_addr.h                  |   1 -
> >  include/hw/virtio/vhost.h                |   1 +
> >  ioport.c                                 |   2 +-
> >  memory.c                                 | 118
> > ++++++++++++++++++++++++++++---
> > numa.c                                   |   2 +- 161 files
> > changed, 867 insertions(+), 458 deletions(-)
> > 
> > -- 
> > 1.8.3.1

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08 14:58     ` Igor Mammedov
@ 2015-07-08 17:30       ` Michael S. Tsirkin
  2015-07-08 18:41         ` Igor Mammedov
  2015-07-08 17:42       ` Paolo Bonzini
  1 sibling, 1 reply; 31+ messages in thread
From: Michael S. Tsirkin @ 2015-07-08 17:30 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: Peter Maydell, QEMU Developers, Paolo Bonzini

On Wed, Jul 08, 2015 at 04:58:37PM +0200, Igor Mammedov wrote:
> On Wed, 8 Jul 2015 12:09:10 +0100
> Peter Maydell <peter.maydell@linaro.org> wrote:
> 
> > On 8 July 2015 at 10:46, Igor Mammedov <imammedo@redhat.com> wrote:
> > > extends memory_region_add_subregion() by adding Error**
> > > argument to allow t fail and return a error from it.
> > >
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > >  156 files changed, 619 insertions(+), 420 deletions(-)
> > 
> > This is a seriously invasive API change and I don't
> > really like it -- reconfiguring the memory region
> > hierarchy should not be an operation which can fail
> > (especially not just adding a subregion!)
> > 
> > -- PMM
> > 
> 
> I'll drop this patch in favor of dedicated
> memory_region_add_subregion_to_hva() API that can fail and return error.

Personally, I think it would be better to have an API that gets
a hva and a callback to invoke before releasing MR.

It's just a question of taste though.

-- 
MST

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08 14:58     ` Igor Mammedov
  2015-07-08 17:30       ` Michael S. Tsirkin
@ 2015-07-08 17:42       ` Paolo Bonzini
  2015-07-08 18:58         ` Igor Mammedov
  1 sibling, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2015-07-08 17:42 UTC (permalink / raw)
  To: Igor Mammedov, Peter Maydell; +Cc: QEMU Developers, Michael S. Tsirkin



On 08/07/2015 16:58, Igor Mammedov wrote:
> I'll drop this patch in favor of dedicated
> memory_region_add_subregion_to_hva() API that can fail and return error.

Isn't the deletion of subregion that is done too early for your work?

You don't want the hot-unplug to complete until all the
address_space_unmaps have completed, if I understand correctly.

Paolo

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08 17:30       ` Michael S. Tsirkin
@ 2015-07-08 18:41         ` Igor Mammedov
  2015-07-09  6:58           ` Michael S. Tsirkin
  0 siblings, 1 reply; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08 18:41 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Peter Maydell, QEMU Developers, Paolo Bonzini

On Wed, 8 Jul 2015 20:30:42 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jul 08, 2015 at 04:58:37PM +0200, Igor Mammedov wrote:
> > On Wed, 8 Jul 2015 12:09:10 +0100
> > Peter Maydell <peter.maydell@linaro.org> wrote:
> > 
> > > On 8 July 2015 at 10:46, Igor Mammedov <imammedo@redhat.com>
> > > wrote:
> > > > extends memory_region_add_subregion() by adding Error**
> > > > argument to allow t fail and return a error from it.
> > > >
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > >  156 files changed, 619 insertions(+), 420 deletions(-)
> > > 
> > > This is a seriously invasive API change and I don't
> > > really like it -- reconfiguring the memory region
> > > hierarchy should not be an operation which can fail
> > > (especially not just adding a subregion!)
> > > 
> > > -- PMM
> > > 
> > 
> > I'll drop this patch in favor of dedicated
> > memory_region_add_subregion_to_hva() API that can fail and return
> > error.
> 
> Personally, I think it would be better to have an API that gets
> a hva and a callback to invoke before releasing MR.
> 
> It's just a question of taste though.
> 

that won't handle check at subregion_add time if region is available
and error out if it's.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08 17:42       ` Paolo Bonzini
@ 2015-07-08 18:58         ` Igor Mammedov
  0 siblings, 0 replies; 31+ messages in thread
From: Igor Mammedov @ 2015-07-08 18:58 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Peter Maydell, QEMU Developers, Michael S. Tsirkin

On Wed, 8 Jul 2015 19:42:21 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> 
> 
> On 08/07/2015 16:58, Igor Mammedov wrote:
> > I'll drop this patch in favor of dedicated
> > memory_region_add_subregion_to_hva() API that can fail and return
> > error.
> 
> Isn't the deletion of subregion that is done too early for your work?
> 
> You don't want the hot-unplug to complete until all the
> address_space_unmaps have completed, if I understand correctly.
yep, region deletion + unmapping from HVA is delayed
until MemoryRegion.destructor is called see 8/8
   memory_region_add_subregion_common() {
       subregion->destructor = memory_region_destructor_hva_ram; 
   }
where default ram destructor is overridden by HVA specific one.

so though delete_subregion() deleted region from current view
that region is still hanging in HVA and old views until ALL
references to it are gone including backend.

When the last reference is gone MemoryRegion.destructor is called and
it unmaps region from HVA range and removes region from hva_mapped_head
list which allows memory_region_add_subregion_to_hva() to check if
range is free to use or error out if it still occupied by old region.

> 
> Paolo

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting
  2015-07-08 18:41         ` Igor Mammedov
@ 2015-07-09  6:58           ` Michael S. Tsirkin
  0 siblings, 0 replies; 31+ messages in thread
From: Michael S. Tsirkin @ 2015-07-09  6:58 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: Peter Maydell, QEMU Developers, Paolo Bonzini

On Wed, Jul 08, 2015 at 08:41:43PM +0200, Igor Mammedov wrote:
> On Wed, 8 Jul 2015 20:30:42 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Jul 08, 2015 at 04:58:37PM +0200, Igor Mammedov wrote:
> > > On Wed, 8 Jul 2015 12:09:10 +0100
> > > Peter Maydell <peter.maydell@linaro.org> wrote:
> > > 
> > > > On 8 July 2015 at 10:46, Igor Mammedov <imammedo@redhat.com>
> > > > wrote:
> > > > > extends memory_region_add_subregion() by adding Error**
> > > > > argument to allow t fail and return a error from it.
> > > > >
> > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > >  156 files changed, 619 insertions(+), 420 deletions(-)
> > > > 
> > > > This is a seriously invasive API change and I don't
> > > > really like it -- reconfiguring the memory region
> > > > hierarchy should not be an operation which can fail
> > > > (especially not just adding a subregion!)
> > > > 
> > > > -- PMM
> > > > 
> > > 
> > > I'll drop this patch in favor of dedicated
> > > memory_region_add_subregion_to_hva() API that can fail and return
> > > error.
> > 
> > Personally, I think it would be better to have an API that gets
> > a hva and a callback to invoke before releasing MR.
> > 
> > It's just a question of taste though.
> > 
> 
> that won't handle check at subregion_add time if region is available
> and error out if it's.

The point is that you request a hva range *before* adding regions.
Then pass it in.

-- 
MST

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-08 15:46   ` Igor Mammedov
@ 2015-07-09 17:04     ` Andrey Korolyov
  2015-07-15 15:18       ` Igor Mammedov
  0 siblings, 1 reply; 31+ messages in thread
From: Andrey Korolyov @ 2015-07-09 17:04 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Paolo Bonzini, Peter Krempa, qemu-devel@nongnu.org,
	Michael S. Tsirkin

On Wed, Jul 8, 2015 at 6:46 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> On Wed, 8 Jul 2015 13:01:05 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
> [...]
>> - this fixes qemu on current kernels, so it's a bugfix
>>
>> - this changes the semantics of memory hot unplug slightly
>>   so I think it's important to merge in 2.4 before we
>>   release qemu with memory hot unplug, this way we
>>   won't have to maintain old semantics forever
> concerning semantic change, I've just chatted with Peter
> who implemented libvirt side of the memory hotplug stack.
> And it's not a problem for libvirt since it always does
> unplug dimm -> remove backend sequence.
>
>


Just for the record - top of the series somehow fixed mysterious guest
memory corruption issue described in
https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg03117.html
which existed right from a moment of a memory hotplug introduction, I
checked series for its disappearance only with vhost for now.  Thanks
Igor!

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-09 17:04     ` Andrey Korolyov
@ 2015-07-15 15:18       ` Igor Mammedov
  2015-07-15 15:26         ` Andrey Korolyov
  0 siblings, 1 reply; 31+ messages in thread
From: Igor Mammedov @ 2015-07-15 15:18 UTC (permalink / raw)
  To: Andrey Korolyov
  Cc: Paolo Bonzini, Peter Krempa, qemu-devel@nongnu.org,
	Michael S. Tsirkin

On Thu, 9 Jul 2015 20:04:35 +0300
Andrey Korolyov <andrey@xdel.ru> wrote:

> On Wed, Jul 8, 2015 at 6:46 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> > On Wed, 8 Jul 2015 13:01:05 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> >
> > [...]
> >> - this fixes qemu on current kernels, so it's a bugfix
> >>
> >> - this changes the semantics of memory hot unplug slightly
> >>   so I think it's important to merge in 2.4 before we
> >>   release qemu with memory hot unplug, this way we
> >>   won't have to maintain old semantics forever
> > concerning semantic change, I've just chatted with Peter
> > who implemented libvirt side of the memory hotplug stack.
> > And it's not a problem for libvirt since it always does
> > unplug dimm -> remove backend sequence.
> >
> >
> 
> 
> Just for the record - top of the series somehow fixed mysterious guest
> memory corruption issue described in
> https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg03117.html
> which existed right from a moment of a memory hotplug introduction, I
> checked series for its disappearance only with vhost for now.  Thanks
> Igor!
just to be sure which patch exactly fixed issue for you?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-15 15:18       ` Igor Mammedov
@ 2015-07-15 15:26         ` Andrey Korolyov
  2015-07-15 16:08           ` Michael S. Tsirkin
  0 siblings, 1 reply; 31+ messages in thread
From: Andrey Korolyov @ 2015-07-15 15:26 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Paolo Bonzini, Peter Krempa, qemu-devel@nongnu.org,
	Michael S. Tsirkin

On Wed, Jul 15, 2015 at 6:18 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> On Thu, 9 Jul 2015 20:04:35 +0300
> Andrey Korolyov <andrey@xdel.ru> wrote:
>
>> On Wed, Jul 8, 2015 at 6:46 PM, Igor Mammedov <imammedo@redhat.com> wrote:
>> > On Wed, 8 Jul 2015 13:01:05 +0300
>> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
>> >
>> > [...]
>> >> - this fixes qemu on current kernels, so it's a bugfix
>> >>
>> >> - this changes the semantics of memory hot unplug slightly
>> >>   so I think it's important to merge in 2.4 before we
>> >>   release qemu with memory hot unplug, this way we
>> >>   won't have to maintain old semantics forever
>> > concerning semantic change, I've just chatted with Peter
>> > who implemented libvirt side of the memory hotplug stack.
>> > And it's not a problem for libvirt since it always does
>> > unplug dimm -> remove backend sequence.
>> >
>> >
>>
>>
>> Just for the record - top of the series somehow fixed mysterious guest
>> memory corruption issue described in
>> https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg03117.html
>> which existed right from a moment of a memory hotplug introduction, I
>> checked series for its disappearance only with vhost for now.  Thanks
>> Igor!
> just to be sure which patch exactly fixed issue for you?
>

Had not bisected this yet, 2.3 is fairly distant from mine production
yet... will post a result today or tomorrow. Until then, I`ll be
absolutely out of clues of what was behind mentioned corruption.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-15 15:26         ` Andrey Korolyov
@ 2015-07-15 16:08           ` Michael S. Tsirkin
  2015-07-15 16:46             ` Andrey Korolyov
  0 siblings, 1 reply; 31+ messages in thread
From: Michael S. Tsirkin @ 2015-07-15 16:08 UTC (permalink / raw)
  To: Andrey Korolyov
  Cc: Igor Mammedov, Peter Krempa, qemu-devel@nongnu.org, Paolo Bonzini

On Wed, Jul 15, 2015 at 06:26:03PM +0300, Andrey Korolyov wrote:
> On Wed, Jul 15, 2015 at 6:18 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> > On Thu, 9 Jul 2015 20:04:35 +0300
> > Andrey Korolyov <andrey@xdel.ru> wrote:
> >
> >> On Wed, Jul 8, 2015 at 6:46 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> >> > On Wed, 8 Jul 2015 13:01:05 +0300
> >> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> >> >
> >> > [...]
> >> >> - this fixes qemu on current kernels, so it's a bugfix
> >> >>
> >> >> - this changes the semantics of memory hot unplug slightly
> >> >>   so I think it's important to merge in 2.4 before we
> >> >>   release qemu with memory hot unplug, this way we
> >> >>   won't have to maintain old semantics forever
> >> > concerning semantic change, I've just chatted with Peter
> >> > who implemented libvirt side of the memory hotplug stack.
> >> > And it's not a problem for libvirt since it always does
> >> > unplug dimm -> remove backend sequence.
> >> >
> >> >
> >>
> >>
> >> Just for the record - top of the series somehow fixed mysterious guest
> >> memory corruption issue described in
> >> https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg03117.html
> >> which existed right from a moment of a memory hotplug introduction, I
> >> checked series for its disappearance only with vhost for now.  Thanks
> >> Igor!
> > just to be sure which patch exactly fixed issue for you?
> >
> 
> Had not bisected this yet, 2.3 is fairly distant from mine production
> yet... will post a result today or tomorrow. Until then, I`ll be
> absolutely out of clues of what was behind mentioned corruption.

Igor merely asked which of his 8 patches fixed it.

-- 
MST

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-15 16:08           ` Michael S. Tsirkin
@ 2015-07-15 16:46             ` Andrey Korolyov
  2015-07-16 20:35               ` Andrey Korolyov
  0 siblings, 1 reply; 31+ messages in thread
From: Andrey Korolyov @ 2015-07-15 16:46 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Igor Mammedov, Peter Krempa, qemu-devel@nongnu.org, Paolo Bonzini

On Wed, Jul 15, 2015 at 7:08 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Wed, Jul 15, 2015 at 06:26:03PM +0300, Andrey Korolyov wrote:
>> On Wed, Jul 15, 2015 at 6:18 PM, Igor Mammedov <imammedo@redhat.com> wrote:
>> > On Thu, 9 Jul 2015 20:04:35 +0300
>> > Andrey Korolyov <andrey@xdel.ru> wrote:
>> >
>> >> On Wed, Jul 8, 2015 at 6:46 PM, Igor Mammedov <imammedo@redhat.com> wrote:
>> >> > On Wed, 8 Jul 2015 13:01:05 +0300
>> >> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
>> >> >
>> >> > [...]
>> >> >> - this fixes qemu on current kernels, so it's a bugfix
>> >> >>
>> >> >> - this changes the semantics of memory hot unplug slightly
>> >> >>   so I think it's important to merge in 2.4 before we
>> >> >>   release qemu with memory hot unplug, this way we
>> >> >>   won't have to maintain old semantics forever
>> >> > concerning semantic change, I've just chatted with Peter
>> >> > who implemented libvirt side of the memory hotplug stack.
>> >> > And it's not a problem for libvirt since it always does
>> >> > unplug dimm -> remove backend sequence.
>> >> >
>> >> >
>> >>
>> >>
>> >> Just for the record - top of the series somehow fixed mysterious guest
>> >> memory corruption issue described in
>> >> https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg03117.html
>> >> which existed right from a moment of a memory hotplug introduction, I
>> >> checked series for its disappearance only with vhost for now.  Thanks
>> >> Igor!
>> > just to be sure which patch exactly fixed issue for you?
>> >
>>
>> Had not bisected this yet, 2.3 is fairly distant from mine production
>> yet... will post a result today or tomorrow. Until then, I`ll be
>> absolutely out of clues of what was behind mentioned corruption.
>
> Igor merely asked which of his 8 patches fixed it.

I mentioned exactly the same thing - right now I`m bisecting over his
series from abovementioned branch to find out what commit fixes the
issue, it should take about a hour for completion of the test series.
The expression is about nature of the bug, as it should be ultimately
weird or well-hidded, given conditions of its exposure.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-15 16:46             ` Andrey Korolyov
@ 2015-07-16 20:35               ` Andrey Korolyov
  2015-07-17 20:45                 ` Andrey Korolyov
  0 siblings, 1 reply; 31+ messages in thread
From: Andrey Korolyov @ 2015-07-16 20:35 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Igor Mammedov, Peter Krempa, qemu-devel@nongnu.org, Paolo Bonzini

On Wed, Jul 15, 2015 at 7:46 PM, Andrey Korolyov <andrey@xdel.ru> wrote:
> On Wed, Jul 15, 2015 at 7:08 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> On Wed, Jul 15, 2015 at 06:26:03PM +0300, Andrey Korolyov wrote:
>>> On Wed, Jul 15, 2015 at 6:18 PM, Igor Mammedov <imammedo@redhat.com> wrote:
>>> > On Thu, 9 Jul 2015 20:04:35 +0300
>>> > Andrey Korolyov <andrey@xdel.ru> wrote:
>>> >
>>> >> On Wed, Jul 8, 2015 at 6:46 PM, Igor Mammedov <imammedo@redhat.com> wrote:
>>> >> > On Wed, 8 Jul 2015 13:01:05 +0300
>>> >> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
>>> >> >
>>> >> > [...]
>>> >> >> - this fixes qemu on current kernels, so it's a bugfix
>>> >> >>
>>> >> >> - this changes the semantics of memory hot unplug slightly
>>> >> >>   so I think it's important to merge in 2.4 before we
>>> >> >>   release qemu with memory hot unplug, this way we
>>> >> >>   won't have to maintain old semantics forever
>>> >> > concerning semantic change, I've just chatted with Peter
>>> >> > who implemented libvirt side of the memory hotplug stack.
>>> >> > And it's not a problem for libvirt since it always does
>>> >> > unplug dimm -> remove backend sequence.
>>> >> >
>>> >> >
>>> >>
>>> >>
>>> >> Just for the record - top of the series somehow fixed mysterious guest
>>> >> memory corruption issue described in
>>> >> https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg03117.html
>>> >> which existed right from a moment of a memory hotplug introduction, I
>>> >> checked series for its disappearance only with vhost for now.  Thanks
>>> >> Igor!
>>> > just to be sure which patch exactly fixed issue for you?
>>> >
>>>
>>> Had not bisected this yet, 2.3 is fairly distant from mine production
>>> yet... will post a result today or tomorrow. Until then, I`ll be
>>> absolutely out of clues of what was behind mentioned corruption.
>>
>> Igor merely asked which of his 8 patches fixed it.
>
> I mentioned exactly the same thing - right now I`m bisecting over his
> series from abovementioned branch to find out what commit fixes the
> issue, it should take about a hour for completion of the test series.
> The expression is about nature of the bug, as it should be ultimately
> weird or well-hidded, given conditions of its exposure.


Whoops.. I`m horribly sorry for the statement above, messed up testing
result in my head. So far, picture looks as following

acf7b7fdf31fa76b53803790917c8acf23a2badb (pre- vhost_one_hp_range_v4
series) - good
e5b3a24181ea0cebf1c5b20f44d016311b7048f0 (2.3.0 tag) - bad

This means that the issue is fixed elsewhere during rc, I am not
promising to find a commit quickly, but I would elaborate as fast as
possible in a spare time. Apologies again for messing things up a
little.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on
  2015-07-16 20:35               ` Andrey Korolyov
@ 2015-07-17 20:45                 ` Andrey Korolyov
  0 siblings, 0 replies; 31+ messages in thread
From: Andrey Korolyov @ 2015-07-17 20:45 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Igor Mammedov, Peter Krempa, qemu-devel@nongnu.org, Paolo Bonzini

> This means that the issue is fixed elsewhere during rc, I am not
> promising to find a commit quickly, but I would elaborate as fast as
> possible in a spare time. Apologies again for messing things up a
> little.

Unfortunately it looks like that the fix is quantative rather than
qualitative - with 2.3.0 it is easier to expose the issue with lower
amount of dimms, while for mentioned tag <8G configurations with 512M
dimms have a very low chance to hit the corruption. I`ve moved test
cycle to the 2G->16G memory update (31 DIMM in total) configuration
and now always experiencing a crash during plug->migration cycle with
running fio job inside. Anyway, commit which reduced the bug
appearance ratio is still a target for me as it can shed some light to
its nature.

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2015-07-17 20:45 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-08  9:46 [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
2015-07-08  9:46 ` [Qemu-devel] [RFC v3 1/8] memory: get rid of memory_region_destructor_ram_from_ptr() Igor Mammedov
2015-07-08  9:46 ` [Qemu-devel] [RFC v3 2/8] memory: introduce MemoryRegion container with reserved HVA range Igor Mammedov
2015-07-08  9:46 ` [Qemu-devel] [RFC v3 3/8] pc: reserve hotpluggable memory range with memory_region_init_hva_range() Igor Mammedov
2015-07-08  9:46 ` [Qemu-devel] [RFC v3 4/8] pc: fix QEMU crashing when more than ~50 memory hotplugged Igor Mammedov
2015-07-08  9:46 ` [Qemu-devel] [RFC v3 5/8] exec: make sure that RAMBlock descriptor won't be leaked Igor Mammedov
2015-07-08  9:46 ` [Qemu-devel] [RFC v3 6/8] exec: add qemu_ram_unmap_hva() API for unmapping memory from HVA area Igor Mammedov
2015-07-08  9:46 ` [Qemu-devel] [RFC v3 7/8] memory: extend memory_region_add_subregion() to support error reporting Igor Mammedov
2015-07-08 11:03   ` Michael S. Tsirkin
2015-07-08 11:09   ` Peter Maydell
2015-07-08 14:58     ` Igor Mammedov
2015-07-08 17:30       ` Michael S. Tsirkin
2015-07-08 18:41         ` Igor Mammedov
2015-07-09  6:58           ` Michael S. Tsirkin
2015-07-08 17:42       ` Paolo Bonzini
2015-07-08 18:58         ` Igor Mammedov
2015-07-08  9:46 ` [Qemu-devel] [RFC v3 8/8] memory: add support for deleting HVA mapped MemoryRegion Igor Mammedov
2015-07-08  9:58   ` Michael S. Tsirkin
2015-07-08 14:43     ` Igor Mammedov
2015-07-08 14:50       ` Michael S. Tsirkin
2015-07-08 10:01 ` [Qemu-devel] [RFC v3 0/8] Fix QEMU crash during memory hotplug with vhost=on Michael S. Tsirkin
2015-07-08 11:41   ` Igor Mammedov
2015-07-08 11:45     ` Michael S. Tsirkin
2015-07-08 15:46   ` Igor Mammedov
2015-07-09 17:04     ` Andrey Korolyov
2015-07-15 15:18       ` Igor Mammedov
2015-07-15 15:26         ` Andrey Korolyov
2015-07-15 16:08           ` Michael S. Tsirkin
2015-07-15 16:46             ` Andrey Korolyov
2015-07-16 20:35               ` Andrey Korolyov
2015-07-17 20:45                 ` Andrey Korolyov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).