[PATCH 3/5] memory: Flush coalesced MMIO on mapping and state changes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Flush pending coalesced MMIO before performing mapping or state changes
that could affect the event orderings or route the buffered requests to
a wrong region.

Signed-off-by: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>

In addition, we also have to
---
 memory.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/memory.c b/memory.c
index ba55b3e..141f92b 100644
--- a/memory.c
+++ b/memory.c
@@ -759,6 +759,7 @@ static void memory_region_update_topology(MemoryRegion *mr)
 
 void memory_region_transaction_begin(void)
 {
+    qemu_flush_coalesced_mmio_buffer();
     ++memory_region_transaction_depth;
 }
 
@@ -1109,6 +1110,9 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 
 void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
 {
+    if (!QTAILQ_EMPTY(&mr->coalesced)) {
+        qemu_flush_coalesced_mmio_buffer();
+    }
     if (mr->readonly != readonly) {
         mr->readonly = readonly;
         memory_region_update_topology(mr);
@@ -1117,6 +1121,9 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
 
 void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
 {
+    if (!QTAILQ_EMPTY(&mr->coalesced)) {
+        qemu_flush_coalesced_mmio_buffer();
+    }
     if (mr->readable != readable) {
         mr->readable = readable;
         memory_region_update_topology(mr);
@@ -1190,6 +1197,8 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
 {
     CoalescedMemoryRange *cmr;
 
+    qemu_flush_coalesced_mmio_buffer();
+
     while (!QTAILQ_EMPTY(&mr->coalesced)) {
         cmr = QTAILQ_FIRST(&mr->coalesced);
         QTAILQ_REMOVE(&mr->coalesced, cmr, link);
@@ -1219,6 +1228,9 @@ void memory_region_add_eventfd(MemoryRegion *mr,
     };
     unsigned i;
 
+    if (!QTAILQ_EMPTY(&mr->coalesced)) {
+        qemu_flush_coalesced_mmio_buffer();
+    }
     for (i = 0; i < mr->ioeventfd_nb; ++i) {
         if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
             break;
@@ -1249,6 +1261,9 @@ void memory_region_del_eventfd(MemoryRegion *mr,
     };
     unsigned i;
 
+    if (!QTAILQ_EMPTY(&mr->coalesced)) {
+        qemu_flush_coalesced_mmio_buffer();
+    }
     for (i = 0; i < mr->ioeventfd_nb; ++i) {
         if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
             break;
@@ -1269,6 +1284,8 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
 {
     MemoryRegion *other;
 
+    qemu_flush_coalesced_mmio_buffer();
+
     assert(!subregion->parent);
     subregion->parent = mr;
     subregion->addr = offset;
@@ -1327,6 +1344,8 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
 void memory_region_del_subregion(MemoryRegion *mr,
                                  MemoryRegion *subregion)
 {
+    qemu_flush_coalesced_mmio_buffer();
+
     assert(subregion->parent == mr);
     subregion->parent = NULL;
     QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
@@ -1335,6 +1354,8 @@ void memory_region_del_subregion(MemoryRegion *mr,
 
 void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
 {
+    qemu_flush_coalesced_mmio_buffer();
+
     if (enabled == mr->enabled) {
         return;
     }
@@ -1367,6 +1388,8 @@ void memory_region_set_alias_offset(MemoryRegion *mr, target_phys_addr_t offset)
 {
     target_phys_addr_t old_offset = mr->alias_offset;
 
+    qemu_flush_coalesced_mmio_buffer();
+
     assert(mr->alias);
     mr->alias_offset = offset;
 
-- 
1.7.3.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux