All of lore.kernel.org
 help / color / mirror / Atom feed
From: Igor Druzhinin <igor.druzhinin@citrix.com>
To: xen-devel@lists.xenproject.org, qemu-devel@nongnu.org
Cc: Igor Druzhinin <igor.druzhinin@citrix.com>,
	sstabellini@kernel.org, anthony.perard@citrix.com,
	paul.durrant@citrix.com, pbonzini@redhat.com
Subject: [Qemu-devel] [PATCH 3/4] xen/mapcache: introduce xen_remap_cache_entry()
Date: Fri, 30 Jun 2017 17:07:04 +0100	[thread overview]
Message-ID: <1498838825-23701-4-git-send-email-igor.druzhinin@citrix.com> (raw)
In-Reply-To: <1498838825-23701-1-git-send-email-igor.druzhinin@citrix.com>

This new call is trying to update a requested map cache entry
according to the changes in the physmap. The call is searching
for the entry, unmaps it, tries to translate the address and
maps again at the same place. If the mapping is dummy this call
will make it real.

This function makes use of a new xenforeignmemory_map2() call
with extended interface that was recently introduced in
libxenforeignmemory [1].

[1] https://www.mail-archive.com/xen-devel@lists.xen.org/msg113007.html

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
 configure                     |  18 ++++++++
 hw/i386/xen/xen-mapcache.c    | 105 +++++++++++++++++++++++++++++++++++++++---
 include/hw/xen/xen_common.h   |   7 +++
 include/sysemu/xen-mapcache.h |   6 +++
 4 files changed, 130 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index c571ad1..ad6156b 100755
--- a/configure
+++ b/configure
@@ -2021,6 +2021,24 @@ EOF
     # Xen unstable
     elif
         cat > $TMPC <<EOF &&
+#undef XC_WANT_COMPAT_MAP_FOREIGN_API
+#include <xenforeignmemory.h>
+int main(void) {
+  xenforeignmemory_handle *xfmem;
+
+  xfmem = xenforeignmemory_open(0, 0);
+  xenforeignmemory_map2(xfmem, 0, 0, 0, 0, 0, 0, 0);
+
+  return 0;
+}
+EOF
+        compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs"
+      then
+      xen_stable_libs="-lxendevicemodel $xen_stable_libs"
+      xen_ctrl_version=41000
+      xen=yes
+    elif
+        cat > $TMPC <<EOF &&
 #undef XC_WANT_COMPAT_DEVICEMODEL_API
 #define __XEN_TOOLS__
 #include <xendevicemodel.h>
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 05050de..5d8d990 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -149,6 +149,7 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
 }
 
 static void xen_remap_bucket(MapCacheEntry *entry,
+                             void *vaddr,
                              hwaddr size,
                              hwaddr address_index,
                              bool dummy)
@@ -179,11 +180,11 @@ static void xen_remap_bucket(MapCacheEntry *entry,
     }
 
     if (!dummy) {
-        vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
-                                           PROT_READ|PROT_WRITE,
+        vaddr_base = xenforeignmemory_map2(xen_fmem, xen_domid, vaddr,
+                                           PROT_READ|PROT_WRITE, 0,
                                            nb_pfn, pfns, err);
         if (vaddr_base == NULL) {
-            perror("xenforeignmemory_map");
+            perror("xenforeignmemory_map2");
             exit(-1);
         }
     } else {
@@ -191,7 +192,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
          * 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(NULL, size, PROT_READ|PROT_WRITE,
+        vaddr_base = mmap(vaddr, size, PROT_READ|PROT_WRITE,
                           MAP_ANON|MAP_SHARED, -1, 0);
         if (vaddr_base == NULL) {
             perror("mmap");
@@ -278,14 +279,14 @@ tryagain:
     if (!entry) {
         entry = g_malloc0(sizeof (MapCacheEntry));
         pentry->next = entry;
-        xen_remap_bucket(entry, cache_size, address_index, dummy);
+        xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
     } 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(entry, cache_size, address_index, dummy);
+            xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
         }
     }
 
@@ -482,3 +483,95 @@ void xen_invalidate_map_cache(void)
 
     mapcache_unlock();
 }
+
+static uint8_t *xen_remap_cache_entry_unlocked(hwaddr phys_addr, hwaddr size)
+{
+    MapCacheEntry *entry, *pentry = NULL;
+    hwaddr address_index;
+    hwaddr address_offset;
+    hwaddr cache_size = size;
+    hwaddr test_bit_size;
+    void *vaddr = NULL;
+    uint8_t lock;
+
+    address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+    /* 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);
+        }
+        cache_size = size + address_offset;
+        if (cache_size % MCACHE_BUCKET_SIZE) {
+            cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE);
+        }
+    } else {
+        test_bit_size = XC_PAGE_SIZE;
+        cache_size = MCACHE_BUCKET_SIZE;
+    }
+
+    /* Search for the requested map cache entry to invalidate */
+    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+    while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr);
+        return NULL;
+    }
+
+    vaddr = entry->vaddr_base;
+    lock = entry->lock;
+    if (entry->vaddr_base) {
+        ram_block_notify_remove(entry->vaddr_base, entry->size);
+        if (munmap(entry->vaddr_base, entry->size) != 0) {
+            perror("unmap fails");
+            exit(-1);
+        }
+    }
+    entry->vaddr_base = NULL;
+    entry->lock = 0;
+
+    if (mapcache->phys_offset_to_gaddr) {
+        phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque);
+
+        address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+        address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+    }
+
+    /* Address may have changed so we need to repeat the search */
+    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+    while (entry && entry->lock && entry->vaddr_base) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        entry = g_malloc0(sizeof (MapCacheEntry));
+        pentry->next = entry;
+    }
+
+    entry->lock = 0;
+    xen_remap_bucket(entry, vaddr, cache_size, address_index, false);
+    if(!test_bits(address_offset >> XC_PAGE_SHIFT,
+                test_bit_size >> XC_PAGE_SHIFT,
+                entry->valid_mapping)) {
+        DPRINTF("Unable to update an entry for %lx in the mapcache!\n", phys_addr);
+        return NULL;
+    }
+
+    entry->lock = lock;
+    return entry->vaddr_base + address_offset;
+}
+
+uint8_t *xen_remap_cache_entry(hwaddr phys_addr, hwaddr size)
+{
+    uint8_t *p;
+
+    mapcache_lock();
+    p = xen_remap_cache_entry_unlocked(phys_addr, size);
+    mapcache_unlock();
+    return p;
+}
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index e00ddd7..70a5cad 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -78,6 +78,13 @@ static inline void *xenforeignmemory_map(xc_interface *h, uint32_t dom,
 
 extern xenforeignmemory_handle *xen_fmem;
 
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
+
+#define xenforeignmemory_map2(h, d, a, p, f, ps, ar, e) \
+    xenforeignmemory_map(h, d, p, ps, ar, e)
+
+#endif
+
 #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40900
 
 typedef xc_interface xendevicemodel_handle;
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 01daaad..8c140d0 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -21,6 +21,7 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
 void xen_invalidate_map_cache_entry(uint8_t *buffer);
 void xen_invalidate_map_cache(void);
+uint8_t *xen_remap_cache_entry(hwaddr phys_addr, hwaddr size);
 
 #else
 
@@ -50,6 +51,11 @@ static inline void xen_invalidate_map_cache(void)
 {
 }
 
+static inline uint8_t *xen_remap_cache_entry(hwaddr phys_addr, hwaddr size)
+{
+    abort();
+}
+
 #endif
 
 #endif /* XEN_MAPCACHE_H */
-- 
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: Igor Druzhinin <igor.druzhinin@citrix.com>
To: xen-devel@lists.xenproject.org, qemu-devel@nongnu.org
Cc: anthony.perard@citrix.com,
	Igor Druzhinin <igor.druzhinin@citrix.com>,
	sstabellini@kernel.org, paul.durrant@citrix.com,
	pbonzini@redhat.com
Subject: [PATCH 3/4] xen/mapcache: introduce xen_remap_cache_entry()
Date: Fri, 30 Jun 2017 17:07:04 +0100	[thread overview]
Message-ID: <1498838825-23701-4-git-send-email-igor.druzhinin@citrix.com> (raw)
In-Reply-To: <1498838825-23701-1-git-send-email-igor.druzhinin@citrix.com>

This new call is trying to update a requested map cache entry
according to the changes in the physmap. The call is searching
for the entry, unmaps it, tries to translate the address and
maps again at the same place. If the mapping is dummy this call
will make it real.

This function makes use of a new xenforeignmemory_map2() call
with extended interface that was recently introduced in
libxenforeignmemory [1].

[1] https://www.mail-archive.com/xen-devel@lists.xen.org/msg113007.html

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
 configure                     |  18 ++++++++
 hw/i386/xen/xen-mapcache.c    | 105 +++++++++++++++++++++++++++++++++++++++---
 include/hw/xen/xen_common.h   |   7 +++
 include/sysemu/xen-mapcache.h |   6 +++
 4 files changed, 130 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index c571ad1..ad6156b 100755
--- a/configure
+++ b/configure
@@ -2021,6 +2021,24 @@ EOF
     # Xen unstable
     elif
         cat > $TMPC <<EOF &&
+#undef XC_WANT_COMPAT_MAP_FOREIGN_API
+#include <xenforeignmemory.h>
+int main(void) {
+  xenforeignmemory_handle *xfmem;
+
+  xfmem = xenforeignmemory_open(0, 0);
+  xenforeignmemory_map2(xfmem, 0, 0, 0, 0, 0, 0, 0);
+
+  return 0;
+}
+EOF
+        compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs"
+      then
+      xen_stable_libs="-lxendevicemodel $xen_stable_libs"
+      xen_ctrl_version=41000
+      xen=yes
+    elif
+        cat > $TMPC <<EOF &&
 #undef XC_WANT_COMPAT_DEVICEMODEL_API
 #define __XEN_TOOLS__
 #include <xendevicemodel.h>
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 05050de..5d8d990 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -149,6 +149,7 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
 }
 
 static void xen_remap_bucket(MapCacheEntry *entry,
+                             void *vaddr,
                              hwaddr size,
                              hwaddr address_index,
                              bool dummy)
@@ -179,11 +180,11 @@ static void xen_remap_bucket(MapCacheEntry *entry,
     }
 
     if (!dummy) {
-        vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
-                                           PROT_READ|PROT_WRITE,
+        vaddr_base = xenforeignmemory_map2(xen_fmem, xen_domid, vaddr,
+                                           PROT_READ|PROT_WRITE, 0,
                                            nb_pfn, pfns, err);
         if (vaddr_base == NULL) {
-            perror("xenforeignmemory_map");
+            perror("xenforeignmemory_map2");
             exit(-1);
         }
     } else {
@@ -191,7 +192,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
          * 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(NULL, size, PROT_READ|PROT_WRITE,
+        vaddr_base = mmap(vaddr, size, PROT_READ|PROT_WRITE,
                           MAP_ANON|MAP_SHARED, -1, 0);
         if (vaddr_base == NULL) {
             perror("mmap");
@@ -278,14 +279,14 @@ tryagain:
     if (!entry) {
         entry = g_malloc0(sizeof (MapCacheEntry));
         pentry->next = entry;
-        xen_remap_bucket(entry, cache_size, address_index, dummy);
+        xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
     } 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(entry, cache_size, address_index, dummy);
+            xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
         }
     }
 
@@ -482,3 +483,95 @@ void xen_invalidate_map_cache(void)
 
     mapcache_unlock();
 }
+
+static uint8_t *xen_remap_cache_entry_unlocked(hwaddr phys_addr, hwaddr size)
+{
+    MapCacheEntry *entry, *pentry = NULL;
+    hwaddr address_index;
+    hwaddr address_offset;
+    hwaddr cache_size = size;
+    hwaddr test_bit_size;
+    void *vaddr = NULL;
+    uint8_t lock;
+
+    address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+    /* 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);
+        }
+        cache_size = size + address_offset;
+        if (cache_size % MCACHE_BUCKET_SIZE) {
+            cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE);
+        }
+    } else {
+        test_bit_size = XC_PAGE_SIZE;
+        cache_size = MCACHE_BUCKET_SIZE;
+    }
+
+    /* Search for the requested map cache entry to invalidate */
+    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+    while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr);
+        return NULL;
+    }
+
+    vaddr = entry->vaddr_base;
+    lock = entry->lock;
+    if (entry->vaddr_base) {
+        ram_block_notify_remove(entry->vaddr_base, entry->size);
+        if (munmap(entry->vaddr_base, entry->size) != 0) {
+            perror("unmap fails");
+            exit(-1);
+        }
+    }
+    entry->vaddr_base = NULL;
+    entry->lock = 0;
+
+    if (mapcache->phys_offset_to_gaddr) {
+        phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque);
+
+        address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+        address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+    }
+
+    /* Address may have changed so we need to repeat the search */
+    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+    while (entry && entry->lock && entry->vaddr_base) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        entry = g_malloc0(sizeof (MapCacheEntry));
+        pentry->next = entry;
+    }
+
+    entry->lock = 0;
+    xen_remap_bucket(entry, vaddr, cache_size, address_index, false);
+    if(!test_bits(address_offset >> XC_PAGE_SHIFT,
+                test_bit_size >> XC_PAGE_SHIFT,
+                entry->valid_mapping)) {
+        DPRINTF("Unable to update an entry for %lx in the mapcache!\n", phys_addr);
+        return NULL;
+    }
+
+    entry->lock = lock;
+    return entry->vaddr_base + address_offset;
+}
+
+uint8_t *xen_remap_cache_entry(hwaddr phys_addr, hwaddr size)
+{
+    uint8_t *p;
+
+    mapcache_lock();
+    p = xen_remap_cache_entry_unlocked(phys_addr, size);
+    mapcache_unlock();
+    return p;
+}
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index e00ddd7..70a5cad 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -78,6 +78,13 @@ static inline void *xenforeignmemory_map(xc_interface *h, uint32_t dom,
 
 extern xenforeignmemory_handle *xen_fmem;
 
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
+
+#define xenforeignmemory_map2(h, d, a, p, f, ps, ar, e) \
+    xenforeignmemory_map(h, d, p, ps, ar, e)
+
+#endif
+
 #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40900
 
 typedef xc_interface xendevicemodel_handle;
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 01daaad..8c140d0 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -21,6 +21,7 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
 void xen_invalidate_map_cache_entry(uint8_t *buffer);
 void xen_invalidate_map_cache(void);
+uint8_t *xen_remap_cache_entry(hwaddr phys_addr, hwaddr size);
 
 #else
 
@@ -50,6 +51,11 @@ static inline void xen_invalidate_map_cache(void)
 {
 }
 
+static inline uint8_t *xen_remap_cache_entry(hwaddr phys_addr, hwaddr size)
+{
+    abort();
+}
+
 #endif
 
 #endif /* XEN_MAPCACHE_H */
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  parent reply	other threads:[~2017-06-30 16:07 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-30 16:07 [Qemu-devel] [PATCH 0/4] xen: don't save/restore the physmap on VM save/restore Igor Druzhinin
2017-06-30 16:07 ` Igor Druzhinin
2017-06-30 16:07 ` [Qemu-devel] [PATCH 1/4] xen: move physmap saving into a separate function Igor Druzhinin
2017-06-30 16:07   ` Igor Druzhinin
2017-07-01  0:06   ` [Qemu-devel] " Stefano Stabellini
2017-07-01  0:06     ` Stefano Stabellini
2017-06-30 16:07 ` [Qemu-devel] [PATCH 2/4] xen/mapcache: add an ability to create dummy mappings Igor Druzhinin
2017-06-30 16:07   ` Igor Druzhinin
2017-07-01  0:06   ` [Qemu-devel] " Stefano Stabellini
2017-07-01  0:06     ` Stefano Stabellini
2017-07-03 20:03     ` [Qemu-devel] " Igor Druzhinin
2017-07-03 20:03       ` Igor Druzhinin
2017-07-03 21:10       ` [Qemu-devel] " Stefano Stabellini
2017-07-03 21:10         ` Stefano Stabellini
2017-06-30 16:07 ` Igor Druzhinin [this message]
2017-06-30 16:07   ` [PATCH 3/4] xen/mapcache: introduce xen_remap_cache_entry() Igor Druzhinin
2017-07-01  0:08   ` [Qemu-devel] " Stefano Stabellini
2017-07-01  0:08     ` Stefano Stabellini
2017-07-03 20:38     ` [Qemu-devel] " Igor Druzhinin
2017-07-03 20:38       ` Igor Druzhinin
2017-06-30 16:07 ` [Qemu-devel] [PATCH 4/4] xen: don't use xenstore to save/restore physmap anymore Igor Druzhinin
2017-06-30 16:07   ` Igor Druzhinin
2017-07-01  0:10   ` [Qemu-devel] " Stefano Stabellini
2017-07-01  0:10     ` Stefano Stabellini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1498838825-23701-4-git-send-email-igor.druzhinin@citrix.com \
    --to=igor.druzhinin@citrix.com \
    --cc=anthony.perard@citrix.com \
    --cc=paul.durrant@citrix.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.