[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC V3 08/12] Intruduce 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 | 29 ++++++++++++++++++++++++++--- xen_mapcache.c | 34 ++++++++++++++++++++++++++++++++++ xen_mapcache.h | 1 + 4 files changed, 62 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 f5888eb..659db50 100644 --- a/exec.c +++ b/exec.c @@ -2959,6 +2959,13 @@ void *qemu_get_ram_ptr(ram_addr_t addr) return NULL; } +void qemu_ram_ptr_unlock(void *addr) +{ + if (xen_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) @@ -3064,6 +3071,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) @@ -3071,19 +3079,21 @@ 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); + stb_p(vaddr = qemu_get_ram_ptr(ram_addr), 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) @@ -3091,19 +3101,21 @@ 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); + stw_p(vaddr = qemu_get_ram_ptr(ram_addr), 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) @@ -3111,13 +3123,14 @@ 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); + stl_p(vaddr = qemu_get_ram_ptr(ram_addr), 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] = { @@ -3537,6 +3550,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 && @@ -3567,6 +3581,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; @@ -3607,6 +3622,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; @@ -3789,6 +3805,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; } @@ -3827,6 +3844,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; } @@ -3867,6 +3885,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; } @@ -3897,6 +3916,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)) { @@ -3939,6 +3959,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); } } @@ -3968,6 +3989,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); @@ -4011,6 +4033,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 8e3bf6c..afa8728 100644 --- a/xen_mapcache.c +++ b/xen_mapcache.c @@ -178,6 +178,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; + unsigned long 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; diff --git a/xen_mapcache.h b/xen_mapcache.h index 5a6730f..3b358b1 100644 --- a/xen_mapcache.h +++ b/xen_mapcache.h @@ -15,6 +15,7 @@ int qemu_map_cache_init(void); uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock); +void qemu_map_cache_unlock(void *phys_addr); ram_addr_t qemu_ram_addr_from_mapcache(void *ptr); void qemu_invalidate_entry(uint8_t *buffer); void qemu_invalidate_map_cache(void); -- 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 |