/*
 * Copyright (C) 2011       Citrix Ltd.
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/error-report.h"

#include <sys/resource.h>

#include "hw/xen/xen-hvm-common.h"
#include "hw/xen/xen_native.h"
#include "qemu/bitmap.h"

#include "sysemu/runstate.h"
#include "sysemu/xen-mapcache.h"
#include "trace.h"

#include <xenevtchn.h>
#include <xengnttab.h>

#if HOST_LONG_BITS == 32
#  define MCACHE_MAX_SIZE     (1UL<<31) /* 2GB Cap */
#else
#  define MCACHE_MAX_SIZE     (1UL<<35) /* 32GB Cap */
#endif

/* This is the size of the virtual address space reserve to QEMU that will not
 * be use by MapCache.
 * From empirical tests I observed that qemu use 75MB more than the
 * max_mcache_size.
 */
#define NON_MCACHE_MEMORY_SIZE (80 * MiB)

typedef struct MapCacheEntry {
    hwaddr paddr_index;
    uint8_t *vaddr_base;
    unsigned long *valid_mapping;
    uint32_t lock;
#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
#define XEN_MAPCACHE_ENTRY_GRANT (1 << 1)
    uint8_t flags;
    hwaddr size;
    struct MapCacheEntry *next;
} MapCacheEntry;

typedef struct MapCacheRev {
    uint8_t *vaddr_req;
    hwaddr paddr_index;
    hwaddr size;
    QTAILQ_ENTRY(MapCacheRev) next;
    bool dma;
} MapCacheRev;

typedef struct MapCache {
    MapCacheEntry *entry;
    unsigned long nr_buckets;
    QTAILQ_HEAD(, MapCacheRev) locked_entries;

    /* For most cases (>99.9%), the page address is the same. */
    MapCacheEntry *last_entry;
    unsigned long max_mcache_size;
    unsigned int bucket_shift;
    unsigned long bucket_size;

    phys_offset_to_gaddr_t phys_offset_to_gaddr;
    QemuMutex lock;
    void *opaque;
} MapCache;

static MapCache *mapcache;
static MapCache *mapcache_grants;
static xengnttab_handle *xen_region_gnttabdev;

static inline void mapcache_lock(MapCache *mc)
{
    qemu_mutex_lock(&mc->lock);
}

static inline void mapcache_unlock(MapCache *mc)
{
    qemu_mutex_unlock(&mc->lock);
}

static inline int test_bits(int nr, int size, const unsigned long *addr)
{
    unsigned long res = find_next_zero_bit(addr, size + nr, nr);
    if (res >= nr + size)
        return 1;
    else
        return 0;
}

static MapCache *xen_map_cache_init_single(phys_offset_to_gaddr_t f,
                                           void *opaque,
                                           unsigned int bucket_shift,
                                           unsigned long max_size)
{
    unsigned long size;
    MapCache *mc;

    assert(bucket_shift >= XC_PAGE_SHIFT);

    mc = g_new0(MapCache, 1);

    mc->phys_offset_to_gaddr = f;
    mc->opaque = opaque;
    qemu_mutex_init(&mc->lock);

    QTAILQ_INIT(&mc->locked_entries);

    mc->bucket_shift = bucket_shift;
    mc->bucket_size = 1UL << bucket_shift;
    mc->max_mcache_size = max_size;

    mc->nr_buckets =
        (((mc->max_mcache_size >> XC_PAGE_SHIFT) +
          (1UL << (bucket_shift - XC_PAGE_SHIFT)) - 1) >>
         (bucket_shift - XC_PAGE_SHIFT));

    size = mc->nr_buckets * sizeof(MapCacheEntry);
    size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
    trace_xen_map_cache_init(mc->nr_buckets, size);
    mc->entry = g_malloc0(size);
    return mc;
}

void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
{
    struct rlimit rlimit_as;
    unsigned long max_mcache_size;
    unsigned int bucket_shift;

    xen_region_gnttabdev = xengnttab_open(NULL, 0);
    if (xen_region_gnttabdev == NULL) {
        error_report("mapcache: Failed to open gnttab device");
        exit(EXIT_FAILURE);
    }

    if (HOST_LONG_BITS == 32) {
        bucket_shift = 16;
    } else {
        bucket_shift = 20;
    }

    if (geteuid() == 0) {
        rlimit_as.rlim_cur = RLIM_INFINITY;
        rlimit_as.rlim_max = RLIM_INFINITY;
        max_mcache_size = MCACHE_MAX_SIZE;
    } else {
        getrlimit(RLIMIT_AS, &rlimit_as);
        rlimit_as.rlim_cur = rlimit_as.rlim_max;

        if (rlimit_as.rlim_max != RLIM_INFINITY) {
            warn_report("QEMU's maximum size of virtual"
                        " memory is not infinity");
        }
        if (rlimit_as.rlim_max < MCACHE_MAX_SIZE + NON_MCACHE_MEMORY_SIZE) {
            max_mcache_size = rlimit_as.rlim_max - NON_MCACHE_MEMORY_SIZE;
        } else {
            max_mcache_size = MCACHE_MAX_SIZE;
        }
    }

    mapcache = xen_map_cache_init_single(f, opaque,
                                         bucket_shift,
                                         max_mcache_size);

    /*
     * Grant mappings must use XC_PAGE_SIZE granularity since we can't
     * map anything beyond the number of pages granted to us.
     */
    mapcache_grants = xen_map_cache_init_single(f, opaque,
                                                XC_PAGE_SHIFT,
                                                max_mcache_size);

    setrlimit(RLIMIT_AS, &rlimit_as);
}

static void xen_remap_bucket(MapCache *mc,
                             MapCacheEntry *entry,
                             void *vaddr,
                             hwaddr size,
                             hwaddr address_index,
                             bool dummy,
                             bool grant,
                             bool is_write,
                             ram_addr_t ram_offset)
{
    uint8_t *vaddr_base;
    g_autofree uint32_t *refs = NULL;
    g_autofree xen_pfn_t *pfns = NULL;
    g_autofree int *err;
    unsigned int i;
    hwaddr nb_pfn = size >> XC_PAGE_SHIFT;

    trace_xen_remap_bucket(address_index);

    if (grant) {
        refs = g_new0(uint32_t, nb_pfn);
    } else {
        pfns = g_new0(xen_pfn_t, nb_pfn);
    }
    err = g_new0(int, nb_pfn);

    if (entry->vaddr_base != NULL) {
        if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
            ram_block_notify_remove(entry->vaddr_base, entry->size,
                                    entry->size);
        }

        /*
         * If an entry is being replaced by another mapping and we're using
         * MAP_FIXED flag for it - there is possibility of a race for vaddr
         * address with another thread doing an mmap call itself
         * (see man 2 mmap). To avoid that we skip explicit unmapping here
         * and allow the kernel to destroy the previous mappings by replacing
         * them in mmap call later.
         *
         * Non-identical replacements are not allowed therefore.
         */
        assert(!vaddr || (entry->vaddr_base == vaddr && entry->size == size));

        if (!vaddr && munmap(entry->vaddr_base, entry->size) != 0) {
            perror("unmap fails");
            exit(-1);
        }
    }
    g_free(entry->valid_mapping);
    entry->valid_mapping = NULL;

    if (grant) {
        hwaddr grant_base = address_index - (ram_offset >> XC_PAGE_SHIFT);

        for (i = 0; i < nb_pfn; i++) {
            refs[i] = grant_base + i;
        }
    } else {
        for (i = 0; i < nb_pfn; i++) {
            pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
        }
    }

    entry->flags &= ~XEN_MAPCACHE_ENTRY_GRANT;

    if (!dummy) {
        if (grant) {
            int prot = PROT_READ;

            if (is_write) {
                prot |= PROT_WRITE;
            }

            entry->flags |= XEN_MAPCACHE_ENTRY_GRANT;
            assert(vaddr == NULL);
            vaddr_base = xengnttab_map_domain_grant_refs(xen_region_gnttabdev,
                                                         nb_pfn,
                                                         xen_domid, refs,
                                                         prot);
        } else {
            /*
             * If the caller has requested the mapping at a specific address use
             * MAP_FIXED to make sure it's honored.
             *
             * We don't yet support upgrading mappings from RO to RW, to handle
             * models using ordinary address_space_rw(), foreign mappings ignore
             * is_write and are always mapped RW.
             */
            vaddr_base = xenforeignmemory_map2(xen_fmem, xen_domid, vaddr,
                                               PROT_READ | PROT_WRITE,
                                               vaddr ? MAP_FIXED : 0,
                                               nb_pfn, pfns, err);
        }
        if (vaddr_base == NULL) {
            perror(grant ? "xengnttab_map_domain_grant_refs"
                           : "xenforeignmemory_map2");
            exit(-1);
        }
    } else {
        /*
         * We create dummy mappings where we are unable to create a foreign
         * mapping immediately due to certain circumstances (i.e. on resume now)
         */
        vaddr_base = mmap(vaddr, size, PROT_READ | PROT_WRITE,
                          MAP_ANON | MAP_SHARED | (vaddr ? MAP_FIXED : 0),
                          -1, 0);
        if (vaddr_base == MAP_FAILED) {
            perror("mmap");
            exit(-1);
        }
    }

    if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
        ram_block_notify_add(vaddr_base, size, size);
    }

    entry->vaddr_base = vaddr_base;
    entry->paddr_index = address_index;
    entry->size = size;
    entry->valid_mapping = g_new0(unsigned long,
                                  BITS_TO_LONGS(size >> XC_PAGE_SHIFT));

    if (dummy) {
        entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
    } else {
        entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
    }

    bitmap_zero(entry->valid_mapping, nb_pfn);
    for (i = 0; i < nb_pfn; i++) {
        if (!err[i]) {
            bitmap_set(entry->valid_mapping, i, 1);
        }
    }
}

static uint8_t *xen_map_cache_unlocked(MapCache *mc,
                                       hwaddr phys_addr, hwaddr size,
                                       ram_addr_t ram_offset,
                                       uint8_t lock, bool dma,
                                       bool grant, bool is_write)
{
    MapCacheEntry *entry, *pentry = NULL,
                  *free_entry = NULL, *free_pentry = NULL;
    hwaddr address_index;
    hwaddr address_offset;
    hwaddr cache_size = size;
    hwaddr test_bit_size;
    bool translated G_GNUC_UNUSED = false;
    bool dummy = false;

tryagain:
    address_index  = phys_addr >> mc->bucket_shift;
    address_offset = phys_addr & (mc->bucket_size - 1);

    trace_xen_map_cache(phys_addr);

    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
    if (size) {
        test_bit_size = size + (phys_addr & (XC_PAGE_SIZE - 1));

        if (test_bit_size % XC_PAGE_SIZE) {
            test_bit_size += XC_PAGE_SIZE - (test_bit_size % XC_PAGE_SIZE);
        }
    } else {
        test_bit_size = XC_PAGE_SIZE;
    }

    if (mc->last_entry != NULL &&
        mc->last_entry->paddr_index == address_index &&
        !lock && !size &&
        test_bits(address_offset >> XC_PAGE_SHIFT,
                  test_bit_size >> XC_PAGE_SHIFT,
                  mc->last_entry->valid_mapping)) {
        trace_xen_map_cache_return(
            mc->last_entry->vaddr_base + address_offset
        );
        return mc->last_entry->vaddr_base + address_offset;
    }

    /* size is always a multiple of mc->bucket_size */
    if (size) {
        cache_size = size + address_offset;
        if (cache_size % mc->bucket_size) {
            cache_size += mc->bucket_size - (cache_size % mc->bucket_size);
        }
    } else {
        cache_size = mc->bucket_size;
    }

    entry = &mc->entry[address_index % mc->nr_buckets];

    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_new0(MapCacheEntry, 1);
        pentry->next = entry;
        xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
                         grant, is_write, ram_offset);
    } else if (!entry->lock) {
        if (!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)) {
            xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
                             grant, is_write, ram_offset);
        }
    }

    if(!test_bits(address_offset >> XC_PAGE_SHIFT,
                test_bit_size >> XC_PAGE_SHIFT,
                entry->valid_mapping)) {
        mc->last_entry = NULL;
#ifdef XEN_COMPAT_PHYSMAP
        if (!translated && mc->phys_offset_to_gaddr) {
            phys_addr = mc->phys_offset_to_gaddr(phys_addr, size);
            translated = true;
            goto tryagain;
        }
#endif
        if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
            dummy = true;
            goto tryagain;
        }
        trace_xen_map_cache_return(NULL);
        return NULL;
    }

    mc->last_entry = entry;
    if (lock) {
        MapCacheRev *reventry = g_new0(MapCacheRev, 1);
        entry->lock++;
        if (entry->lock == 0) {
            error_report("mapcache entry lock overflow: "HWADDR_FMT_plx" -> %p",
                         entry->paddr_index, entry->vaddr_base);
            abort();
        }
        reventry->dma = dma;
        reventry->vaddr_req = mc->last_entry->vaddr_base + address_offset;
        reventry->paddr_index = mc->last_entry->paddr_index;
        reventry->size = entry->size;
        QTAILQ_INSERT_HEAD(&mc->locked_entries, reventry, next);
    }

    trace_xen_map_cache_return(
        mc->last_entry->vaddr_base + address_offset
    );
    return mc->last_entry->vaddr_base + address_offset;
}

uint8_t *xen_map_cache(MemoryRegion *mr,
                       hwaddr phys_addr, hwaddr size,
                       ram_addr_t ram_addr_offset,
                       uint8_t lock, bool dma,
                       bool is_write)
{
    bool grant = xen_mr_is_grants(mr);
    MapCache *mc = grant ? mapcache_grants : mapcache;
    uint8_t *p;

    if (grant && !lock) {
        /*
         * Grants are only supported via address_space_map(). Anything
         * else is considered a user/guest error.
         *
         * QEMU generally doesn't expect these mappings to ever fail, so
         * if this happens we report an error message and abort().
         */
        error_report("Tried to access a grant reference without mapping it.");
        abort();
    }

    mapcache_lock(mc);
    p = xen_map_cache_unlocked(mc, phys_addr, size, ram_addr_offset,
                               lock, dma, grant, is_write);
    mapcache_unlock(mc);
    return p;
}

static ram_addr_t xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
{
    MapCacheEntry *entry = NULL;
    MapCacheRev *reventry;
    hwaddr paddr_index;
    hwaddr size;
    ram_addr_t raddr;
    int found = 0;

    mapcache_lock(mc);
    QTAILQ_FOREACH(reventry, &mc->locked_entries, next) {
        if (reventry->vaddr_req == ptr) {
            paddr_index = reventry->paddr_index;
            size = reventry->size;
            found = 1;
            break;
        }
    }
    if (!found) {
        trace_xen_ram_addr_from_mapcache_not_found(ptr);
        mapcache_unlock(mc);
        return RAM_ADDR_INVALID;
    }

    entry = &mc->entry[paddr_index % mc->nr_buckets];
    while (entry && (entry->paddr_index != paddr_index || entry->size != size)) {
        entry = entry->next;
    }
    if (!entry) {
        trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
        raddr = RAM_ADDR_INVALID;
    } else {
        raddr = (reventry->paddr_index << mc->bucket_shift) +
             ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
    }
    mapcache_unlock(mc);
    return raddr;
}

ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
{
    ram_addr_t addr;

    addr = xen_ram_addr_from_mapcache_single(mapcache, ptr);
    if (addr == RAM_ADDR_INVALID) {
        addr = xen_ram_addr_from_mapcache_single(mapcache_grants, ptr);
    }

    return addr;
}

static void xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
                                                    uint8_t *buffer)
{
    MapCacheEntry *entry = NULL, *pentry = NULL;
    MapCacheRev *reventry;
    hwaddr paddr_index;
    hwaddr size;
    int found = 0;
    int rc;

    QTAILQ_FOREACH(reventry, &mc->locked_entries, next) {
        if (reventry->vaddr_req == buffer) {
            paddr_index = reventry->paddr_index;
            size = reventry->size;
            found = 1;
            break;
        }
    }
    if (!found) {
        trace_xen_invalidate_map_cache_entry_unlocked_not_found(buffer);
        QTAILQ_FOREACH(reventry, &mc->locked_entries, next) {
            trace_xen_invalidate_map_cache_entry_unlocked_found(
                reventry->paddr_index,
                reventry->vaddr_req
            );
        }
        return;
    }
    QTAILQ_REMOVE(&mc->locked_entries, reventry, next);
    g_free(reventry);

    if (mc->last_entry != NULL &&
        mc->last_entry->paddr_index == paddr_index) {
        mc->last_entry = NULL;
    }

    entry = &mc->entry[paddr_index % mc->nr_buckets];
    while (entry && (entry->paddr_index != paddr_index || entry->size != size)) {
        pentry = entry;
        entry = entry->next;
    }
    if (!entry) {
        trace_xen_invalidate_map_cache_entry_unlocked_miss(buffer);
        return;
    }
    entry->lock--;
    if (entry->lock > 0) {
        return;
    }

    ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
    if (entry->flags & XEN_MAPCACHE_ENTRY_GRANT) {
        rc = xengnttab_unmap(xen_region_gnttabdev, entry->vaddr_base,
                             entry->size >> mc->bucket_shift);
    } else {
        rc = munmap(entry->vaddr_base, entry->size);
    }

    if (rc) {
        perror("unmap fails");
        exit(-1);
    }

    g_free(entry->valid_mapping);
    if (pentry) {
        pentry->next = entry->next;
        g_free(entry);
    } else {
        /*
         * Invalidate mapping but keep entry->next pointing to the rest
         * of the list.
         *
         * Note that lock is already zero here, otherwise we don't unmap.
         */
        entry->paddr_index = 0;
        entry->vaddr_base = NULL;
        entry->valid_mapping = NULL;
        entry->flags = 0;
        entry->size = 0;
    }
}

typedef struct XenMapCacheData {
    Coroutine *co;
    uint8_t *buffer;
} XenMapCacheData;

static void xen_invalidate_map_cache_entry_single(MapCache *mc, uint8_t *buffer)
{
    mapcache_lock(mc);
    xen_invalidate_map_cache_entry_unlocked(mc, buffer);
    mapcache_unlock(mc);
}

static void xen_invalidate_map_cache_entry_all(uint8_t *buffer)
{
    xen_invalidate_map_cache_entry_single(mapcache, buffer);
    xen_invalidate_map_cache_entry_single(mapcache_grants, buffer);
}

static void xen_invalidate_map_cache_entry_bh(void *opaque)
{
    XenMapCacheData *data = opaque;

    xen_invalidate_map_cache_entry_all(data->buffer);
    aio_co_wake(data->co);
}

void coroutine_mixed_fn xen_invalidate_map_cache_entry(uint8_t *buffer)
{
    if (qemu_in_coroutine()) {
        XenMapCacheData data = {
            .co = qemu_coroutine_self(),
            .buffer = buffer,
        };
        aio_bh_schedule_oneshot(qemu_get_current_aio_context(),
                                xen_invalidate_map_cache_entry_bh, &data);
        qemu_coroutine_yield();
    } else {
        xen_invalidate_map_cache_entry_all(buffer);
    }
}

static void xen_invalidate_map_cache_single(MapCache *mc)
{
    unsigned long i;
    MapCacheRev *reventry;

    mapcache_lock(mc);

    QTAILQ_FOREACH(reventry, &mc->locked_entries, next) {
        if (!reventry->dma) {
            continue;
        }
        trace_xen_invalidate_map_cache(reventry->paddr_index,
                                       reventry->vaddr_req);
    }

    for (i = 0; i < mc->nr_buckets; i++) {
        MapCacheEntry *entry = &mc->entry[i];

        if (entry->vaddr_base == NULL) {
            continue;
        }
        if (entry->lock > 0) {
            continue;
        }

        if (munmap(entry->vaddr_base, entry->size) != 0) {
            perror("unmap fails");
            exit(-1);
        }

        entry->paddr_index = 0;
        entry->vaddr_base = NULL;
        entry->size = 0;
        g_free(entry->valid_mapping);
        entry->valid_mapping = NULL;
    }

    mc->last_entry = NULL;

    mapcache_unlock(mc);
}

void xen_invalidate_map_cache(void)
{
    /* Flush pending AIO before destroying the mapcache */
    bdrv_drain_all();

    xen_invalidate_map_cache_single(mapcache);
    xen_invalidate_map_cache_single(mapcache_grants);
}

static uint8_t *xen_replace_cache_entry_unlocked(MapCache *mc,
                                                 hwaddr old_phys_addr,
                                                 hwaddr new_phys_addr,
                                                 hwaddr size)
{
    MapCacheEntry *entry;
    hwaddr address_index, address_offset;
    hwaddr test_bit_size, cache_size = size;

    address_index  = old_phys_addr >> mc->bucket_shift;
    address_offset = old_phys_addr & (mc->bucket_size - 1);

    assert(size);
    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
    test_bit_size = size + (old_phys_addr & (XC_PAGE_SIZE - 1));
    if (test_bit_size % XC_PAGE_SIZE) {
        test_bit_size += XC_PAGE_SIZE - (test_bit_size % XC_PAGE_SIZE);
    }
    cache_size = size + address_offset;
    if (cache_size % mc->bucket_size) {
        cache_size += mc->bucket_size - (cache_size % mc->bucket_size);
    }

    entry = &mc->entry[address_index % mc->nr_buckets];
    while (entry && !(entry->paddr_index == address_index &&
                      entry->size == cache_size)) {
        entry = entry->next;
    }
    if (!entry) {
        trace_xen_replace_cache_entry_unlocked(old_phys_addr);
        return NULL;
    }

    assert((entry->flags & XEN_MAPCACHE_ENTRY_GRANT) == 0);

    address_index  = new_phys_addr >> mc->bucket_shift;
    address_offset = new_phys_addr & (mc->bucket_size - 1);

    trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);

    xen_remap_bucket(mc, entry, entry->vaddr_base,
                     cache_size, address_index, false,
                     false, false, old_phys_addr);
    if (!test_bits(address_offset >> XC_PAGE_SHIFT,
                test_bit_size >> XC_PAGE_SHIFT,
                entry->valid_mapping)) {
        trace_xen_replace_cache_entry_unlocked_could_not_update_entry(
            old_phys_addr
        );
        return NULL;
    }

    return entry->vaddr_base + address_offset;
}

uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
                                 hwaddr new_phys_addr,
                                 hwaddr size)
{
    uint8_t *p;

    mapcache_lock(mapcache);
    p = xen_replace_cache_entry_unlocked(mapcache, old_phys_addr,
                                         new_phys_addr, size);
    mapcache_unlock(mapcache);
    return p;
}
