aboutsummaryrefslogtreecommitdiff
path: root/hw/i386/xen/xen-mapcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/i386/xen/xen-mapcache.c')
-rw-r--r--hw/i386/xen/xen-mapcache.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index bb1078c..369c3df 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;