WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[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

<Prev in Thread] Current Thread [Next in Thread>