From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=54936 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P0btC-00066b-DQ for qemu-devel@nongnu.org; Tue, 28 Sep 2010 11:14:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1P0bsq-0007y8-H3 for qemu-devel@nongnu.org; Tue, 28 Sep 2010 11:14:21 -0400 Received: from mail-yx0-f173.google.com ([209.85.213.173]:45427) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1P0bsq-0007y2-Cl for qemu-devel@nongnu.org; Tue, 28 Sep 2010 11:14:20 -0400 Received: by yxf34 with SMTP id 34so495026yxf.4 for ; Tue, 28 Sep 2010 08:14:19 -0700 (PDT) Message-ID: <4CA2064A.7020701@codemonkey.ws> Date: Tue, 28 Sep 2010 10:14:18 -0500 From: Anthony Liguori MIME-Version: 1.0 References: <1285686097-13036-1-git-send-email-anthony.perard@citrix.com> <1285686097-13036-11-git-send-email-anthony.perard@citrix.com> In-Reply-To: <1285686097-13036-11-git-send-email-anthony.perard@citrix.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] Re: [PATCH RFC V4 10/14] Introduce qemu_ram_ptr_unlock. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: anthony.perard@citrix.com Cc: xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano.Stabellini@eu.citrix.com On 09/28/2010 10:01 AM, anthony.perard@citrix.com wrote: > From: Anthony PERARD > > 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 > Why isn't hooking cpu_physical_memory_{map,unmap}() not enough? That's really the intention of the API. You only really care about guest RAM, not device memory, correct? Regards, Anthony Liguori > --- > 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; > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anthony Liguori Subject: Re: [PATCH RFC V4 10/14] Introduce qemu_ram_ptr_unlock. Date: Tue, 28 Sep 2010 10:14:18 -0500 Message-ID: <4CA2064A.7020701@codemonkey.ws> References: <1285686097-13036-1-git-send-email-anthony.perard@citrix.com> <1285686097-13036-11-git-send-email-anthony.perard@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1285686097-13036-11-git-send-email-anthony.perard@citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: anthony.perard@citrix.com Cc: xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano.Stabellini@eu.citrix.com List-Id: xen-devel@lists.xenproject.org On 09/28/2010 10:01 AM, anthony.perard@citrix.com wrote: > From: Anthony PERARD > > 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 > Why isn't hooking cpu_physical_memory_{map,unmap}() not enough? That's really the intention of the API. You only really care about guest RAM, not device memory, correct? Regards, Anthony Liguori > --- > 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; >