summary refs log tree commit diff stats
path: root/hw/i386/xen/xen-mapcache.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-07-24 10:01:15 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-07-24 10:01:15 +0100
commitdf95f1a298a3e16c80293343143dcedbe7978f6c (patch)
tree5d847a03b9f475ac7ca6f8005cc2aba4d2470907 /hw/i386/xen/xen-mapcache.c
parent91939262ffcd3c85ea6a4793d3029326eea1d649 (diff)
parent7fb394ad8a7c4609cefa2136dec16cf65d028f40 (diff)
downloadfocaccia-qemu-df95f1a298a3e16c80293343143dcedbe7978f6c.tar.gz
focaccia-qemu-df95f1a298a3e16c80293343143dcedbe7978f6c.zip
Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20170721-tag' into staging
Xen 2017/07/21

# gpg: Signature made Sat 22 Jul 2017 01:43:34 BST
# gpg:                using RSA key 0x894F8F4870E1AE90
# gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>"
# gpg:                 aka "Stefano Stabellini <sstabellini@kernel.org>"
# Primary key fingerprint: D04E 33AB A51F 67BA 07D3  0AEA 894F 8F48 70E1 AE90

* remotes/sstabellini/tags/xen-20170721-tag:
  xen-mapcache: Fix the bug when overlapping emulated DMA operations may cause inconsistency in guest memory mappings
  xen: fix compilation on 32-bit hosts

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i386/xen/xen-mapcache.c')
-rw-r--r--hw/i386/xen/xen-mapcache.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 2a1fbd13cc..369c3df8a0 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -234,7 +234,8 @@ static void xen_remap_bucket(MapCacheEntry *entry,
 static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
                                        uint8_t lock, bool dma)
 {
-    MapCacheEntry *entry, *pentry = NULL;
+    MapCacheEntry *entry, *pentry = NULL,
+                  *free_entry = NULL, *free_pentry = NULL;
     hwaddr address_index;
     hwaddr address_offset;
     hwaddr cache_size = size;
@@ -281,14 +282,22 @@ tryagain:
 
     entry = &mapcache->entry[address_index % mapcache->nr_buckets];
 
-    while (entry && entry->lock && entry->vaddr_base &&
+    while (entry && (lock || entry->lock) && entry->vaddr_base &&
             (entry->paddr_index != address_index || entry->size != cache_size ||
              !test_bits(address_offset >> XC_PAGE_SHIFT,
                  test_bit_size >> XC_PAGE_SHIFT,
                  entry->valid_mapping))) {
+        if (!free_entry && !entry->lock) {
+            free_entry = entry;
+            free_pentry = pentry;
+        }
         pentry = entry;
         entry = entry->next;
     }
+    if (!entry && free_entry) {
+        entry = free_entry;
+        pentry = free_pentry;
+    }
     if (!entry) {
         entry = g_malloc0(sizeof (MapCacheEntry));
         pentry->next = entry;
@@ -527,7 +536,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
         entry = entry->next;
     }
     if (!entry) {
-        DPRINTF("Trying to update an entry for %lx " \
+        DPRINTF("Trying to update an entry for "TARGET_FMT_plx \
                 "that is not in the mapcache!\n", old_phys_addr);
         return NULL;
     }
@@ -535,15 +544,16 @@ static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
     address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
     address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
 
-    fprintf(stderr, "Replacing a dummy mapcache entry for %lx with %lx\n",
-            old_phys_addr, new_phys_addr);
+    fprintf(stderr, "Replacing a dummy mapcache entry for "TARGET_FMT_plx \
+            " with "TARGET_FMT_plx"\n", old_phys_addr, new_phys_addr);
 
     xen_remap_bucket(entry, entry->vaddr_base,
                      cache_size, address_index, false);
     if (!test_bits(address_offset >> XC_PAGE_SHIFT,
                 test_bit_size >> XC_PAGE_SHIFT,
                 entry->valid_mapping)) {
-        DPRINTF("Unable to update a mapcache entry for %lx!\n", old_phys_addr);
+        DPRINTF("Unable to update a mapcache entry for "TARGET_FMT_plx"!\n",
+                old_phys_addr);
         return NULL;
     }