diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-07-24 10:01:15 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-07-24 10:01:15 +0100 |
commit | df95f1a298a3e16c80293343143dcedbe7978f6c (patch) | |
tree | 5d847a03b9f475ac7ca6f8005cc2aba4d2470907 | |
parent | 91939262ffcd3c85ea6a4793d3029326eea1d649 (diff) | |
parent | 7fb394ad8a7c4609cefa2136dec16cf65d028f40 (diff) |
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>
-rw-r--r-- | hw/i386/xen/xen-mapcache.c | 22 |
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; } |