Patchwork [1/3] Replacing memory_region_add_subregion_overlap

login
register
mail settings
Submitter Alexey Korolev
Date Feb. 18, 2013, 11:12 p.m.
Message ID <1361229171-23902-2-git-send-email-akorolex@gmail.com>
Download mbox | patch
Permalink /patch/221553/
State New
Headers show

Comments

Alexey Korolev - Feb. 18, 2013, 11:12 p.m.
At the moment qemu memory manager considers every memory region as
overlappable. Thus the function memory_region_add_subregion_overlap can
only set the priority of the region.
Code will be more clear if we use only the memory_region_add_subregion
function to add a subregion to a container, and optionally use
memory_region_set_priority() to change priority from the default.
This patch adds predefined priority values in memory.h. Priority can take
one of 4 possible values: low (default), medium, high and exclusive
(highest).

Signed-off-by: Alexey Korolev <akorolex@gmail.com>
---
 hw/armv7m_nvic.c      |    4 ++--
 hw/cirrus_vga.c       |   15 ++++++++-------
 hw/kvm/pci-assign.c   |    7 +++----
 hw/kvmvapic.c         |    3 ++-
 hw/lpc_ich9.c         |    7 ++++---
 hw/onenand.c          |    7 +++----
 hw/pam.c              |    4 ++--
 hw/pc.c               |    6 ++----
 hw/pc_sysfw.c         |   14 ++++++--------
 hw/pci/pci.c          |    4 ++--
 hw/pci/pci_bridge.c   |    3 ++-
 hw/piix_pci.c         |    9 +++++----
 hw/q35.c              |    5 +++--
 hw/sysbus.c           |    7 -------
 hw/sysbus.h           |    2 --
 hw/vga-isa.c          |    7 ++++---
 hw/vga.c              |   12 ++++++------
 hw/xen_pt_msi.c       |    6 +++---
 include/exec/memory.h |   41 ++++++++++++++++++++---------------------
 memory.c              |   36 +++++++++++++++++-------------------
 20 files changed, 94 insertions(+), 105 deletions(-)

Patch

diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index d5798d0..0710356 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -496,8 +496,8 @@  static int armv7m_nvic_init(SysBusDevice *dev)
      */
     memory_region_init_alias(&s->gic_iomem_alias, "nvic-gic", &s->gic.iomem,
                              0x100, 0xc00);
-    memory_region_add_subregion_overlap(&s->container, 0x100,
-                                        &s->gic_iomem_alias, 1);
+    memory_region_set_priority(&s->gic_iomem_alias, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(&s->container, 0x100, &s->gic_iomem_alias);
     /* Map the whole thing into system memory at the location required
      * by the v7M architecture.
      */
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 2a2c8da..70f04ff 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2386,7 +2386,8 @@  static void map_linear_vram(CirrusVGAState *s)
 {
     if (s->bustype == CIRRUS_BUSTYPE_PCI && !s->linear_vram) {
         s->linear_vram = true;
-        memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
+        memory_region_set_priority(&s->vga.vram, MR_PRIORITY_MEDIUM);
+        memory_region_add_subregion(&s->pci_bar, 0, &s->vga.vram);
     }
     map_linear_vram_bank(s, 0);
     map_linear_vram_bank(s, 1);
@@ -2850,13 +2851,13 @@  static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
         MemoryRegion *bank = &s->cirrus_bank[i];
         memory_region_init_alias(bank, names[i], &s->vga.vram, 0, 0x8000);
         memory_region_set_enabled(bank, false);
-        memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000,
-                                            bank, 1);
+        memory_region_set_priority(bank, MR_PRIORITY_MEDIUM);
+        memory_region_add_subregion(&s->low_mem_container, i * 0x8000, bank);
     }
-    memory_region_add_subregion_overlap(system_memory,
-                                        isa_mem_base + 0x000a0000,
-                                        &s->low_mem_container,
-                                        1);
+    memory_region_set_priority(&s->low_mem_container, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(system_memory,
+                                isa_mem_base + 0x000a0000,
+                                &s->low_mem_container);
     memory_region_set_coalescing(&s->low_mem);
 
     /* I/O handler for LFB */
diff --git a/hw/kvm/pci-assign.c b/hw/kvm/pci-assign.c
index da64b5b..5da41cf 100644
--- a/hw/kvm/pci-assign.c
+++ b/hw/kvm/pci-assign.c
@@ -308,10 +308,9 @@  static void assigned_dev_iomem_setup(PCIDevice *pci_dev, int region_num,
                 r_dev->msix_table_addr) {
             uint64_t offset = r_dev->msix_table_addr - real_region->base_addr;
 
-            memory_region_add_subregion_overlap(&region->container,
-                                                offset,
-                                                &r_dev->mmio,
-                                                1);
+            memory_region_set_priority(&r_dev->mmio, MR_PRIORITY_MEDIUM);
+            memory_region_add_subregion(&region->container,
+                                        offset, &r_dev->mmio);
         }
     }
 }
diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c
index 1b5f416..3e10eba 100644
--- a/hw/kvmvapic.c
+++ b/hw/kvmvapic.c
@@ -598,7 +598,8 @@  static void vapic_map_rom_writable(VAPICROMState *s)
 
     memory_region_init_alias(&s->rom, "kvmvapic-rom", section.mr, rom_paddr,
                              rom_size);
-    memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000);
+    memory_region_set_priority(&s->rom, MR_PRIORITY_EXCLUSIVE);
+    memory_region_add_subregion(as, rom_paddr, &s->rom);
     s->rom_mapped_writable = true;
 }
 
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
index e25689b..e5b6e0d 100644
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@ -404,9 +404,10 @@  static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old)
             memory_region_del_subregion(get_system_memory(), &lpc->rbca_mem);
     }
     if (rbca & ICH9_LPC_RCBA_EN) {
-            memory_region_add_subregion_overlap(get_system_memory(),
-                                                rbca & ICH9_LPC_RCBA_BA_MASK,
-                                                &lpc->rbca_mem, 1);
+            memory_region_set_priority(&lpc->rbca_mem, MR_PRIORITY_MEDIUM);
+            memory_region_add_subregion(get_system_memory(),
+                                        rbca & ICH9_LPC_RCBA_BA_MASK,
+                                        &lpc->rbca_mem);
     }
 }
 
diff --git a/hw/onenand.c b/hw/onenand.c
index 00a8738..ea1e309 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -118,10 +118,9 @@  static void onenand_mem_setup(OneNANDState *s)
     memory_region_init_alias(&s->mapped_ram, "onenand-mapped-ram",
                              &s->ram, 0x0200 << s->shift,
                              0xbe00 << s->shift);
-    memory_region_add_subregion_overlap(&s->container,
-                                        0x0200 << s->shift,
-                                        &s->mapped_ram,
-                                        1);
+    memory_region_set_priority(&s->mapped_ram, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(&s->container, 0x0200 << s->shift,
+                                &s->mapped_ram);
 }
 
 static void onenand_intr_update(OneNANDState *s)
diff --git a/hw/pam.c b/hw/pam.c
index 1d72e88..33391ef 100644
--- a/hw/pam.c
+++ b/hw/pam.c
@@ -71,8 +71,8 @@  void init_pam(MemoryRegion *ram_memory, MemoryRegion *system_memory,
 
     for (i = 0; i < 4; ++i) {
         memory_region_set_enabled(&mem->alias[i], false);
-        memory_region_add_subregion_overlap(system_memory, start,
-                                            &mem->alias[i], 1);
+        memory_region_set_priority(&mem->alias[i], MR_PRIORITY_MEDIUM);
+        memory_region_add_subregion(system_memory, start, &mem->alias[i]);
     }
     mem->current = 0;
 }
diff --git a/hw/pc.c b/hw/pc.c
index 53cc173..a48479a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -949,10 +949,8 @@  void *pc_memory_init(MemoryRegion *system_memory,
     option_rom_mr = g_malloc(sizeof(*option_rom_mr));
     memory_region_init_ram(option_rom_mr, "pc.rom", PC_ROM_SIZE);
     vmstate_register_ram_global(option_rom_mr);
-    memory_region_add_subregion_overlap(rom_memory,
-                                        PC_ROM_MIN_VGA,
-                                        option_rom_mr,
-                                        1);
+    memory_region_set_priority(option_rom_mr, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(rom_memory, PC_ROM_MIN_VGA, option_rom_mr);
 
     fw_cfg = bochs_bios_init();
     rom_set_fw(fw_cfg);
diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c
index 7f6c12c..96ec366 100644
--- a/hw/pc_sysfw.c
+++ b/hw/pc_sysfw.c
@@ -59,10 +59,10 @@  static void pc_isa_bios_init(MemoryRegion *rom_memory,
     isa_bios = g_malloc(sizeof(*isa_bios));
     memory_region_init_ram(isa_bios, "isa-bios", isa_bios_size);
     vmstate_register_ram_global(isa_bios);
-    memory_region_add_subregion_overlap(rom_memory,
-                                        0x100000 - isa_bios_size,
-                                        isa_bios,
-                                        1);
+    memory_region_set_priority(isa_bios, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(rom_memory,
+                                0x100000 - isa_bios_size,
+                                isa_bios);
 
     /* copy ISA rom image from top of flash memory */
     flash_ptr = memory_region_get_ram_ptr(flash_mem);
@@ -181,10 +181,8 @@  static void old_pc_system_rom_init(MemoryRegion *rom_memory)
     isa_bios = g_malloc(sizeof(*isa_bios));
     memory_region_init_alias(isa_bios, "isa-bios", bios,
                              bios_size - isa_bios_size, isa_bios_size);
-    memory_region_add_subregion_overlap(rom_memory,
-                                        0x100000 - isa_bios_size,
-                                        isa_bios,
-                                        1);
+    memory_region_set_priority(isa_bios, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(rom_memory, 0x100000 - isa_bios_size, isa_bios);
     memory_region_set_readonly(isa_bios, true);
 
     /* map all the bios at the top of memory */
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 2f45c8f..b9e92ea 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1032,8 +1032,8 @@  static void pci_update_mappings(PCIDevice *d)
         }
         r->addr = new_addr;
         if (r->addr != PCI_BAR_UNMAPPED) {
-            memory_region_add_subregion_overlap(r->address_space,
-                                                r->addr, r->memory, 1);
+            memory_region_set_priority(r->memory, MR_PRIORITY_MEDIUM);
+            memory_region_add_subregion(r->address_space, r->addr, r->memory);
         }
     }
 }
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index 995842a..71d4e40 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -148,7 +148,8 @@  static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
     pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0;
 
     memory_region_init_alias(alias, name, space, base, size);
-    memory_region_add_subregion_overlap(parent_space, base, alias, 1);
+    memory_region_set_priority(alias, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(parent_space, base, alias);
 }
 
 static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 6c77e49..659b6fa 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -269,8 +269,8 @@  static PCIBus *i440fx_common_init(const char *device_name,
     }
     memory_region_init_alias(&f->smram_region, "smram-region",
                              f->pci_address_space, 0xa0000, 0x20000);
-    memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
-                                        &f->smram_region, 1);
+    memory_region_set_priority(&f->smram_region, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(f->system_memory, 0xa0000, &f->smram_region);
     memory_region_set_enabled(&f->smram_region, false);
     init_pam(f->ram_memory, f->system_memory, f->pci_address_space,
              &f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
@@ -547,8 +547,9 @@  static int piix3_initfn(PCIDevice *dev)
     isa_bus_new(&d->dev.qdev, pci_address_space_io(dev));
 
     memory_region_init_io(&d->rcr_mem, &rcr_ops, d, "piix3-reset-control", 1);
-    memory_region_add_subregion_overlap(pci_address_space_io(dev), RCR_IOPORT,
-                                        &d->rcr_mem, 1);
+    memory_region_set_priority(&d->rcr_mem, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(pci_address_space_io(dev), RCR_IOPORT,
+                                &d->rcr_mem);
 
     qemu_register_reset(piix3_reset, d);
     return 0;
diff --git a/hw/q35.c b/hw/q35.c
index efebc27..b67e79b 100644
--- a/hw/q35.c
+++ b/hw/q35.c
@@ -264,8 +264,9 @@  static int mch_init(PCIDevice *d)
     cpu_smm_register(&mch_set_smm, mch);
     memory_region_init_alias(&mch->smram_region, "smram-region",
                              mch->pci_address_space, 0xa0000, 0x20000);
-    memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
-                                        &mch->smram_region, 1);
+    memory_region_set_priority(&mch->smram_region, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(mch->system_memory, 0xa0000,
+                                &mch->smram_region);
     memory_region_set_enabled(&mch->smram_region, false);
     init_pam(mch->ram_memory, mch->system_memory, mch->pci_address_space,
              &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 6d9d1df..5dfdf78 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -220,13 +220,6 @@  void sysbus_add_memory(SysBusDevice *dev, hwaddr addr,
     memory_region_add_subregion(get_system_memory(), addr, mem);
 }
 
-void sysbus_add_memory_overlap(SysBusDevice *dev, hwaddr addr,
-                               MemoryRegion *mem, unsigned priority)
-{
-    memory_region_add_subregion_overlap(get_system_memory(), addr, mem,
-                                        priority);
-}
-
 void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem)
 {
     memory_region_del_subregion(get_system_memory(), mem);
diff --git a/hw/sysbus.h b/hw/sysbus.h
index a7fcded..88f5e1c 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -58,8 +58,6 @@  void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr);
 void sysbus_add_memory(SysBusDevice *dev, hwaddr addr,
                        MemoryRegion *mem);
-void sysbus_add_memory_overlap(SysBusDevice *dev, hwaddr addr,
-                               MemoryRegion *mem, unsigned priority);
 void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem);
 void sysbus_add_io(SysBusDevice *dev, hwaddr addr,
                    MemoryRegion *mem);
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 762e45a..776fa31 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -58,9 +58,10 @@  static int vga_initfn(ISADevice *dev)
     if (vbe_ports) {
         isa_register_portio_list(dev, 0x1ce, vbe_ports, s, "vbe");
     }
-    memory_region_add_subregion_overlap(isa_address_space(dev),
-                                        isa_mem_base + 0x000a0000,
-                                        vga_io_memory, 1);
+    memory_region_set_priority(vga_io_memory, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(isa_address_space(dev),
+                                isa_mem_base + 0x000a0000,
+                                vga_io_memory);
     memory_region_set_coalescing(vga_io_memory);
     s->ds = graphic_console_init(s->update, s->invalidate,
                                  s->screen_dump, s->text_update, s);
diff --git a/hw/vga.c b/hw/vga.c
index e2ba7f2..f16f77b 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -202,8 +202,8 @@  static void vga_update_memory_access(VGACommonState *s)
         base += isa_mem_base;
         region = g_malloc(sizeof(*region));
         memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
-        memory_region_add_subregion_overlap(s->legacy_address_space, base,
-                                            region, 2);
+        memory_region_set_priority(region, MR_PRIORITY_HIGH);
+        memory_region_add_subregion(s->legacy_address_space, base, region);
         s->chain4_alias = region;
     }
     if (old_region) {
@@ -2359,10 +2359,10 @@  void vga_init(VGACommonState *s, MemoryRegion *address_space,
     s->legacy_address_space = address_space;
 
     vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
-    memory_region_add_subregion_overlap(address_space,
-                                        isa_mem_base + 0x000a0000,
-                                        vga_io_memory,
-                                        1);
+    memory_region_set_priority(vga_io_memory, MR_PRIORITY_MEDIUM);
+    memory_region_add_subregion(address_space,
+                                isa_mem_base + 0x000a0000,
+                                vga_io_memory);
     memory_region_set_coalescing(vga_io_memory);
     if (init_vga_ports) {
         portio_list_init(vga_port_list, vga_ports, s, "vga");
diff --git a/hw/xen_pt_msi.c b/hw/xen_pt_msi.c
index db757cd..85353ed 100644
--- a/hw/xen_pt_msi.c
+++ b/hw/xen_pt_msi.c
@@ -583,9 +583,9 @@  int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)
     XEN_PT_LOG(d, "mapping physical MSI-X table to %p\n",
                msix->phys_iomem_base);
 
-    memory_region_add_subregion_overlap(&s->bar[bar_index], table_off,
-                                        &msix->mmio,
-                                        2); /* Priority: pci default + 1 */
+    /* Priority: pci default + 1 */
+    memory_region_set_priority(&msix->mmio, MR_PRIORITY_HIGH);
+    memory_region_add_subregion(&s->bar[bar_index], table_off, &msix->mmio);
 
     return 0;
 
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 2322732..162bdba 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -38,6 +38,11 @@  typedef struct MemoryRegionMmio MemoryRegionMmio;
 #define DIRTY_MEMORY_CODE      1
 #define DIRTY_MEMORY_MIGRATION 3
 
+#define MR_PRIORITY_LOW       0
+#define MR_PRIORITY_MEDIUM    1
+#define MR_PRIORITY_HIGH      2
+#define MR_PRIORITY_EXCLUSIVE 3
+
 struct MemoryRegionMmio {
     CPUReadMemoryFunc *read[3];
     CPUWriteMemoryFunc *write[3];
@@ -642,27 +647,6 @@  void memory_region_del_eventfd(MemoryRegion *mr,
 void memory_region_add_subregion(MemoryRegion *mr,
                                  hwaddr offset,
                                  MemoryRegion *subregion);
-/**
- * memory_region_add_subregion_overlap: Add a subregion to a container
- *                                      with overlap.
- *
- * Adds a subregion at @offset.  The subregion may overlap with other
- * subregions.  Conflicts are resolved by having a higher @priority hide a
- * lower @priority. Subregions without priority are taken as @priority 0.
- * A region may only be added once as a subregion (unless removed with
- * memory_region_del_subregion()); use memory_region_init_alias() if you
- * want a region to be a subregion in multiple locations.
- *
- * @mr: the region to contain the new subregion; must be a container
- *      initialized with memory_region_init().
- * @offset: the offset relative to @mr where @subregion is added.
- * @subregion: the subregion to be added.
- * @priority: used for resolving overlaps; highest priority wins.
- */
-void memory_region_add_subregion_overlap(MemoryRegion *mr,
-                                         hwaddr offset,
-                                         MemoryRegion *subregion,
-                                         unsigned priority);
 
 /**
  * memory_region_get_ram_addr: Get the ram address associated with a memory
@@ -722,6 +706,21 @@  void memory_region_set_address(MemoryRegion *mr, hwaddr addr);
 void memory_region_set_alias_offset(MemoryRegion *mr,
                                     hwaddr offset);
 
+/*
+ * memory_region_set_priority: dynamically update the priority of a region
+ *
+ * Dynamically updates the priority of a region. The default @priority of
+ * the subregion is MR_PRIORITY_LOW. If one memory region overlaps another
+ * the conflicts are resolved by having a higher @priority hide a lower
+ * @priority.
+ * May be used on regions are currently part of a memory hierarchy.
+ *
+ * @mr: the region to be updated
+ * @priority: used for resolving overlaps; highest priority wins.
+ */
+void memory_region_set_priority(MemoryRegion *mr,
+                                unsigned priority);
+
 /**
  * memory_region_find: locate a MemoryRegion in an address space
  *
diff --git a/memory.c b/memory.c
index 92a2196..ec5aa57 100644
--- a/memory.c
+++ b/memory.c
@@ -805,7 +805,7 @@  void memory_region_init(MemoryRegion *mr,
     mr->readonly = false;
     mr->rom_device = false;
     mr->destructor = memory_region_destructor_none;
-    mr->priority = 0;
+    mr->priority = MR_PRIORITY_LOW;
     mr->may_overlap = false;
     mr->alias = NULL;
     QTAILQ_INIT(&mr->subregions);
@@ -1359,17 +1359,6 @@  void memory_region_add_subregion(MemoryRegion *mr,
     subregion->priority = 0;
     memory_region_add_subregion_common(mr, offset, subregion);
 }
-
-void memory_region_add_subregion_overlap(MemoryRegion *mr,
-                                         hwaddr offset,
-                                         MemoryRegion *subregion,
-                                         unsigned priority)
-{
-    subregion->may_overlap = true;
-    subregion->priority = priority;
-    memory_region_add_subregion_common(mr, offset, subregion);
-}
-
 void memory_region_del_subregion(MemoryRegion *mr,
                                  MemoryRegion *subregion)
 {
@@ -1395,8 +1384,6 @@  void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
 void memory_region_set_address(MemoryRegion *mr, hwaddr addr)
 {
     MemoryRegion *parent = mr->parent;
-    unsigned priority = mr->priority;
-    bool may_overlap = mr->may_overlap;
 
     if (addr == mr->addr || !parent) {
         mr->addr = addr;
@@ -1405,11 +1392,7 @@  void memory_region_set_address(MemoryRegion *mr, hwaddr addr)
 
     memory_region_transaction_begin();
     memory_region_del_subregion(parent, mr);
-    if (may_overlap) {
-        memory_region_add_subregion_overlap(parent, addr, mr, priority);
-    } else {
-        memory_region_add_subregion(parent, addr, mr);
-    }
+    memory_region_add_subregion(parent, addr, mr);
     memory_region_transaction_commit();
 }
 
@@ -1427,6 +1410,21 @@  void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset)
     memory_region_transaction_commit();
 }
 
+void memory_region_set_priority(MemoryRegion *mr, unsigned priority)
+{
+    MemoryRegion *parent = mr->parent;
+
+    mr->priority = priority;
+    if (!parent) {
+        return;
+    }
+
+    memory_region_transaction_begin();
+    memory_region_del_subregion(parent, mr);
+    memory_region_add_subregion(parent, mr->addr, mr);
+    memory_region_transaction_commit();
+}
+
 ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
 {
     return mr->ram_addr;