[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC V4 10/14] Introduce qemu_ram_ptr_unlock.
From: Anthony PERARD <anthony.perard@xxxxxxxxxx> This function allows to unlock a ram_ptr give by qemu_get_ram_ptr. After a call to qemu_ram_ptr_unlock, the pointer may be unmap from QEMU when used with Xen. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- cpu-common.h | 1 + exec.c | 32 +++++++++++++++++++++++++++++--- xen-mapcache.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index 0426bc8..378eea8 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -46,6 +46,7 @@ ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size); void qemu_ram_free(ram_addr_t addr); /* This should only be used for ram local to a device. */ void *qemu_get_ram_ptr(ram_addr_t addr); +void qemu_ram_ptr_unlock(void *addr); /* This should not be used by devices. */ ram_addr_t qemu_ram_addr_from_host(void *ptr); diff --git a/exec.c b/exec.c index 0de9e32..0612ee4 100644 --- a/exec.c +++ b/exec.c @@ -2961,6 +2961,13 @@ void *qemu_get_ram_ptr(ram_addr_t addr) return NULL; } +void qemu_ram_ptr_unlock(void *addr) +{ + if (xen_mapcache_enabled()) { + qemu_map_cache_unlock(addr); + } +} + /* Some of the softmmu routines need to translate from a host pointer (typically a TLB entry) back to a ram offset. */ ram_addr_t qemu_ram_addr_from_host(void *ptr) @@ -3067,6 +3074,7 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr, uint32_t val) { int dirty_flags; + void *vaddr; dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); if (!(dirty_flags & CODE_DIRTY_FLAG)) { #if !defined(CONFIG_USER_ONLY) @@ -3074,19 +3082,22 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr, dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); #endif } - stb_p(qemu_get_ram_ptr(ram_addr), val); + vaddr = qemu_get_ram_ptr(ram_addr); + stb_p(vaddr, val); dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); /* we remove the notdirty callback only if the code has been flushed */ if (dirty_flags == 0xff) tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); + qemu_ram_ptr_unlock(vaddr); } static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr, uint32_t val) { int dirty_flags; + void *vaddr; dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); if (!(dirty_flags & CODE_DIRTY_FLAG)) { #if !defined(CONFIG_USER_ONLY) @@ -3094,19 +3105,22 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr, dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); #endif } - stw_p(qemu_get_ram_ptr(ram_addr), val); + vaddr = qemu_get_ram_ptr(ram_addr); + stw_p(vaddr, val); dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); /* we remove the notdirty callback only if the code has been flushed */ if (dirty_flags == 0xff) tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); + qemu_ram_ptr_unlock(vaddr); } static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr, uint32_t val) { int dirty_flags; + void *vaddr; dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); if (!(dirty_flags & CODE_DIRTY_FLAG)) { #if !defined(CONFIG_USER_ONLY) @@ -3114,13 +3128,15 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr, dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); #endif } - stl_p(qemu_get_ram_ptr(ram_addr), val); + vaddr = qemu_get_ram_ptr(ram_addr); + stl_p(vaddr, val); dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); /* we remove the notdirty callback only if the code has been flushed */ if (dirty_flags == 0xff) tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); + qemu_ram_ptr_unlock(vaddr); } static CPUReadMemoryFunc * const error_mem_read[3] = { @@ -3540,6 +3556,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, cpu_physical_memory_set_dirty_flags( addr1, (0xff & ~CODE_DIRTY_FLAG)); } + qemu_ram_ptr_unlock(ptr); } } else { if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && @@ -3570,6 +3587,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); memcpy(buf, ptr, l); + qemu_ram_ptr_unlock(ptr); } } len -= l; @@ -3610,6 +3628,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, /* ROM/RAM case */ ptr = qemu_get_ram_ptr(addr1); memcpy(ptr, buf, l); + qemu_ram_ptr_unlock(ptr); } len -= l; buf += l; @@ -3792,6 +3811,7 @@ uint32_t ldl_phys(target_phys_addr_t addr) ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); val = ldl_p(ptr); + qemu_ram_ptr_unlock(ptr); } return val; } @@ -3830,6 +3850,7 @@ uint64_t ldq_phys(target_phys_addr_t addr) ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); val = ldq_p(ptr); + qemu_ram_ptr_unlock(ptr); } return val; } @@ -3870,6 +3891,7 @@ uint32_t lduw_phys(target_phys_addr_t addr) ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); val = lduw_p(ptr); + qemu_ram_ptr_unlock(ptr); } return val; } @@ -3900,6 +3922,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val) unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); ptr = qemu_get_ram_ptr(addr1); stl_p(ptr, val); + qemu_ram_ptr_unlock(ptr); if (unlikely(in_migration)) { if (!cpu_physical_memory_is_dirty(addr1)) { @@ -3942,6 +3965,7 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val) ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); stq_p(ptr, val); + qemu_ram_ptr_unlock(ptr); } } @@ -3971,6 +3995,7 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) /* RAM case */ ptr = qemu_get_ram_ptr(addr1); stl_p(ptr, val); + qemu_ram_ptr_unlock(ptr); if (!cpu_physical_memory_is_dirty(addr1)) { /* invalidate code */ tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); @@ -4014,6 +4039,7 @@ void stw_phys(target_phys_addr_t addr, uint32_t val) /* RAM case */ ptr = qemu_get_ram_ptr(addr1); stw_p(ptr, val); + qemu_ram_ptr_unlock(ptr); if (!cpu_physical_memory_is_dirty(addr1)) { /* invalidate code */ tb_invalidate_phys_page_range(addr1, addr1 + 2, 0); diff --git a/xen-mapcache.c b/xen-mapcache.c index c7e69e6..e407949 100644 --- a/xen-mapcache.c +++ b/xen-mapcache.c @@ -187,6 +187,40 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u return mapcache->last_address_vaddr + address_offset; } +void qemu_map_cache_unlock(void *buffer) +{ + MapCacheEntry *entry = NULL, *pentry = NULL; + MapCacheRev *reventry; + target_phys_addr_t paddr_index; + int found = 0; + + QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) { + if (reventry->vaddr_req == buffer) { + paddr_index = reventry->paddr_index; + found = 1; + break; + } + } + if (!found) { + return; + } + QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next); + qemu_free(reventry); + + entry = &mapcache->entry[paddr_index % mapcache->nr_buckets]; + while (entry && entry->paddr_index != paddr_index) { + pentry = entry; + entry = entry->next; + } + if (!entry) { + return; + } + entry->lock--; + if (entry->lock > 0) { + entry->lock--; + } +} + ram_addr_t qemu_ram_addr_from_mapcache(void *ptr) { MapCacheRev *reventry; -- 1.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |