All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/4] xen: don't save/restore the physmap on VM save/restore
@ 2017-07-04 15:47 ` Igor Druzhinin
  0 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: Igor Druzhinin, sstabellini, anthony.perard, paul.durrant, pbonzini

Saving/restoring the physmap to/from xenstore was introduced to
QEMU majorly in order to cover up the VRAM region restore issue.
The sequence of restore operations implies that we should know
the effective guest VRAM address *before* we have the VRAM region
restored (which happens later). Unfortunately, in Xen environment
VRAM memory does actually belong to a guest - not QEMU itself -
which means the position of this region is unknown beforehand and
can't be mapped into QEMU address space immediately.

Previously, recreating xenstore keys, holding the physmap, by the
toolstack helped to get this information in place at the right
moment ready to be consumed by QEMU to map the region properly.
But using xenstore for it has certain disadvantages: toolstack
needs to be aware of these keys and save/restore them accordingly;
accessing xenstore requires extra privileges which hinders QEMU
sandboxing.

The previous attempt to get rid of that was to remember all the
VRAM pointers during QEMU initialization phase and then update
them all at once when an actual foreign mapping is established.
Unfortunately, this approach worked only for VRAM and only for
a predefined set of devices - stdvga and cirrus. QXL and other
possible future devices using a moving emulated MMIO region
would be equally broken.

The new approach leverages xenforeignmemory_map2() call recently
introduced in libxenforeignmemory. It allows to create a dummy
anonymous mapping for QEMU during its initialization and change
it to a real one later during machine state restore.

---
Changed in v2:
* Patch 2: set dummy flag in a new flags field in struct MapCacheEntry
* Patch 3: change xen_remap_cache_entry name and signature
* Patch 3: gate ram_block_notify_* functions in xen_remap_bucket
* Patch 3: rewrite the logic of xen_replace_cache_entry_unlocked to
           reuse the existing entry instead of allocating a new one
* Patch 4: don't use xen_phys_offset_to_gaddr in non-compat mode

---
Igor Druzhinin (4):
  xen: move physmap saving into a separate function
  xen/mapcache: add an ability to create dummy mappings
  xen/mapcache: introduce xen_replace_cache_entry()
  xen: don't use xenstore to save/restore physmap anymore

 configure                     |  18 +++++++
 hw/i386/xen/xen-hvm.c         | 105 ++++++++++++++++++++++++++---------------
 hw/i386/xen/xen-mapcache.c    | 107 ++++++++++++++++++++++++++++++++++++++----
 include/hw/xen/xen_common.h   |   8 ++++
 include/sysemu/xen-mapcache.h |  11 ++++-
 5 files changed, 201 insertions(+), 48 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v2 0/4] xen: don't save/restore the physmap on VM save/restore
@ 2017-07-04 15:47 ` Igor Druzhinin
  0 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: anthony.perard, Igor Druzhinin, sstabellini, paul.durrant, pbonzini

Saving/restoring the physmap to/from xenstore was introduced to
QEMU majorly in order to cover up the VRAM region restore issue.
The sequence of restore operations implies that we should know
the effective guest VRAM address *before* we have the VRAM region
restored (which happens later). Unfortunately, in Xen environment
VRAM memory does actually belong to a guest - not QEMU itself -
which means the position of this region is unknown beforehand and
can't be mapped into QEMU address space immediately.

Previously, recreating xenstore keys, holding the physmap, by the
toolstack helped to get this information in place at the right
moment ready to be consumed by QEMU to map the region properly.
But using xenstore for it has certain disadvantages: toolstack
needs to be aware of these keys and save/restore them accordingly;
accessing xenstore requires extra privileges which hinders QEMU
sandboxing.

The previous attempt to get rid of that was to remember all the
VRAM pointers during QEMU initialization phase and then update
them all at once when an actual foreign mapping is established.
Unfortunately, this approach worked only for VRAM and only for
a predefined set of devices - stdvga and cirrus. QXL and other
possible future devices using a moving emulated MMIO region
would be equally broken.

The new approach leverages xenforeignmemory_map2() call recently
introduced in libxenforeignmemory. It allows to create a dummy
anonymous mapping for QEMU during its initialization and change
it to a real one later during machine state restore.

---
Changed in v2:
* Patch 2: set dummy flag in a new flags field in struct MapCacheEntry
* Patch 3: change xen_remap_cache_entry name and signature
* Patch 3: gate ram_block_notify_* functions in xen_remap_bucket
* Patch 3: rewrite the logic of xen_replace_cache_entry_unlocked to
           reuse the existing entry instead of allocating a new one
* Patch 4: don't use xen_phys_offset_to_gaddr in non-compat mode

---
Igor Druzhinin (4):
  xen: move physmap saving into a separate function
  xen/mapcache: add an ability to create dummy mappings
  xen/mapcache: introduce xen_replace_cache_entry()
  xen: don't use xenstore to save/restore physmap anymore

 configure                     |  18 +++++++
 hw/i386/xen/xen-hvm.c         | 105 ++++++++++++++++++++++++++---------------
 hw/i386/xen/xen-mapcache.c    | 107 ++++++++++++++++++++++++++++++++++++++----
 include/hw/xen/xen_common.h   |   8 ++++
 include/sysemu/xen-mapcache.h |  11 ++++-
 5 files changed, 201 insertions(+), 48 deletions(-)

-- 
2.7.4


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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [Qemu-devel] [PATCH v2 1/4] xen: move physmap saving into a separate function
  2017-07-04 15:47 ` Igor Druzhinin
@ 2017-07-04 15:47   ` Igor Druzhinin
  -1 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: Igor Druzhinin, sstabellini, anthony.perard, paul.durrant, pbonzini

Non-functional change.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
 hw/i386/xen/xen-hvm.c | 57 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index cffa7e2..d259cf7 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -305,6 +305,36 @@ static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
     return start_addr;
 }
 
+static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
+{
+    char path[80], value[17];
+
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
+            xen_domid, (uint64_t)physmap->phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->start_addr);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
+            xen_domid, (uint64_t)physmap->phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    if (physmap->name) {
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
+                xen_domid, (uint64_t)physmap->phys_offset);
+        if (!xs_write(state->xenstore, 0, path,
+                      physmap->name, strlen(physmap->name))) {
+            return -1;
+        }
+    }
+    return 0;
+}
+
 static int xen_add_to_physmap(XenIOState *state,
                               hwaddr start_addr,
                               ram_addr_t size,
@@ -316,7 +346,6 @@ static int xen_add_to_physmap(XenIOState *state,
     XenPhysmap *physmap = NULL;
     hwaddr pfn, start_gpfn;
     hwaddr phys_offset = memory_region_get_ram_addr(mr);
-    char path[80], value[17];
     const char *mr_name;
 
     if (get_physmapping(state, start_addr, size)) {
@@ -368,31 +397,7 @@ go_physmap:
                                    start_addr >> TARGET_PAGE_BITS,
                                    (start_addr + size - 1) >> TARGET_PAGE_BITS,
                                    XEN_DOMCTL_MEM_CACHEATTR_WB);
-
-    snprintf(path, sizeof(path),
-            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
-            xen_domid, (uint64_t)phys_offset);
-    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
-    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
-        return -1;
-    }
-    snprintf(path, sizeof(path),
-            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
-            xen_domid, (uint64_t)phys_offset);
-    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
-    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
-        return -1;
-    }
-    if (mr_name) {
-        snprintf(path, sizeof(path),
-                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
-                xen_domid, (uint64_t)phys_offset);
-        if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
-            return -1;
-        }
-    }
-
-    return 0;
+    return xen_save_physmap(state, physmap);
 }
 
 static int xen_remove_from_physmap(XenIOState *state,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 1/4] xen: move physmap saving into a separate function
@ 2017-07-04 15:47   ` Igor Druzhinin
  0 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: anthony.perard, Igor Druzhinin, sstabellini, paul.durrant, pbonzini

Non-functional change.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
 hw/i386/xen/xen-hvm.c | 57 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index cffa7e2..d259cf7 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -305,6 +305,36 @@ static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
     return start_addr;
 }
 
+static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
+{
+    char path[80], value[17];
+
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
+            xen_domid, (uint64_t)physmap->phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->start_addr);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
+            xen_domid, (uint64_t)physmap->phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    if (physmap->name) {
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
+                xen_domid, (uint64_t)physmap->phys_offset);
+        if (!xs_write(state->xenstore, 0, path,
+                      physmap->name, strlen(physmap->name))) {
+            return -1;
+        }
+    }
+    return 0;
+}
+
 static int xen_add_to_physmap(XenIOState *state,
                               hwaddr start_addr,
                               ram_addr_t size,
@@ -316,7 +346,6 @@ static int xen_add_to_physmap(XenIOState *state,
     XenPhysmap *physmap = NULL;
     hwaddr pfn, start_gpfn;
     hwaddr phys_offset = memory_region_get_ram_addr(mr);
-    char path[80], value[17];
     const char *mr_name;
 
     if (get_physmapping(state, start_addr, size)) {
@@ -368,31 +397,7 @@ go_physmap:
                                    start_addr >> TARGET_PAGE_BITS,
                                    (start_addr + size - 1) >> TARGET_PAGE_BITS,
                                    XEN_DOMCTL_MEM_CACHEATTR_WB);
-
-    snprintf(path, sizeof(path),
-            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
-            xen_domid, (uint64_t)phys_offset);
-    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
-    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
-        return -1;
-    }
-    snprintf(path, sizeof(path),
-            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
-            xen_domid, (uint64_t)phys_offset);
-    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
-    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
-        return -1;
-    }
-    if (mr_name) {
-        snprintf(path, sizeof(path),
-                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
-                xen_domid, (uint64_t)phys_offset);
-        if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
-            return -1;
-        }
-    }
-
-    return 0;
+    return xen_save_physmap(state, physmap);
 }
 
 static int xen_remove_from_physmap(XenIOState *state,
-- 
2.7.4


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

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [Qemu-devel] [PATCH v2 2/4] xen/mapcache: add an ability to create dummy mappings
  2017-07-04 15:47 ` Igor Druzhinin
@ 2017-07-04 15:47   ` Igor Druzhinin
  -1 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: Igor Druzhinin, sstabellini, anthony.perard, paul.durrant, pbonzini

Dummys are simple anonymous mappings that are placed instead
of regular foreign mappings in certain situations when we need
to postpone the actual mapping but still have to give a
memory region to QEMU to play with.

This is planned to be used for restore on Xen.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
 hw/i386/xen/xen-mapcache.c | 40 ++++++++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 8 deletions(-)

diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index e60156c..cd4e746 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -53,6 +53,8 @@ typedef struct MapCacheEntry {
     uint8_t *vaddr_base;
     unsigned long *valid_mapping;
     uint8_t lock;
+#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
+    uint8_t flags;
     hwaddr size;
     struct MapCacheEntry *next;
 } MapCacheEntry;
@@ -150,7 +152,8 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
 
 static void xen_remap_bucket(MapCacheEntry *entry,
                              hwaddr size,
-                             hwaddr address_index)
+                             hwaddr address_index,
+                             bool dummy)
 {
     uint8_t *vaddr_base;
     xen_pfn_t *pfns;
@@ -177,11 +180,27 @@ static void xen_remap_bucket(MapCacheEntry *entry,
         pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
     }
 
-    vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
-                                      nb_pfn, pfns, err);
-    if (vaddr_base == NULL) {
-        perror("xenforeignmemory_map");
-        exit(-1);
+    if (!dummy) {
+        vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
+                                           PROT_READ|PROT_WRITE,
+                                           nb_pfn, pfns, err);
+        if (vaddr_base == NULL) {
+            perror("xenforeignmemory_map");
+            exit(-1);
+        }
+        entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
+    } else {
+        /*
+         * 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,
+                          MAP_ANON|MAP_SHARED, -1, 0);
+        if (vaddr_base == NULL) {
+            perror("mmap");
+            exit(-1);
+        }
+        entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
     }
 
     entry->vaddr_base = vaddr_base;
@@ -211,6 +230,7 @@ static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
     hwaddr cache_size = size;
     hwaddr test_bit_size;
     bool translated = false;
+    bool dummy = false;
 
 tryagain:
     address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
@@ -262,14 +282,14 @@ tryagain:
     if (!entry) {
         entry = g_malloc0(sizeof (MapCacheEntry));
         pentry->next = entry;
-        xen_remap_bucket(entry, cache_size, address_index);
+        xen_remap_bucket(entry, 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);
+            xen_remap_bucket(entry, cache_size, address_index, dummy);
         }
     }
 
@@ -282,6 +302,10 @@ tryagain:
             translated = true;
             goto tryagain;
         }
+        if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
+            dummy = true;
+            goto tryagain;
+        }
         trace_xen_map_cache_return(NULL);
         return NULL;
     }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 2/4] xen/mapcache: add an ability to create dummy mappings
@ 2017-07-04 15:47   ` Igor Druzhinin
  0 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: anthony.perard, Igor Druzhinin, sstabellini, paul.durrant, pbonzini

Dummys are simple anonymous mappings that are placed instead
of regular foreign mappings in certain situations when we need
to postpone the actual mapping but still have to give a
memory region to QEMU to play with.

This is planned to be used for restore on Xen.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
 hw/i386/xen/xen-mapcache.c | 40 ++++++++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 8 deletions(-)

diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index e60156c..cd4e746 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -53,6 +53,8 @@ typedef struct MapCacheEntry {
     uint8_t *vaddr_base;
     unsigned long *valid_mapping;
     uint8_t lock;
+#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
+    uint8_t flags;
     hwaddr size;
     struct MapCacheEntry *next;
 } MapCacheEntry;
@@ -150,7 +152,8 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
 
 static void xen_remap_bucket(MapCacheEntry *entry,
                              hwaddr size,
-                             hwaddr address_index)
+                             hwaddr address_index,
+                             bool dummy)
 {
     uint8_t *vaddr_base;
     xen_pfn_t *pfns;
@@ -177,11 +180,27 @@ static void xen_remap_bucket(MapCacheEntry *entry,
         pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
     }
 
-    vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
-                                      nb_pfn, pfns, err);
-    if (vaddr_base == NULL) {
-        perror("xenforeignmemory_map");
-        exit(-1);
+    if (!dummy) {
+        vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
+                                           PROT_READ|PROT_WRITE,
+                                           nb_pfn, pfns, err);
+        if (vaddr_base == NULL) {
+            perror("xenforeignmemory_map");
+            exit(-1);
+        }
+        entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
+    } else {
+        /*
+         * 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,
+                          MAP_ANON|MAP_SHARED, -1, 0);
+        if (vaddr_base == NULL) {
+            perror("mmap");
+            exit(-1);
+        }
+        entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
     }
 
     entry->vaddr_base = vaddr_base;
@@ -211,6 +230,7 @@ static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
     hwaddr cache_size = size;
     hwaddr test_bit_size;
     bool translated = false;
+    bool dummy = false;
 
 tryagain:
     address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
@@ -262,14 +282,14 @@ tryagain:
     if (!entry) {
         entry = g_malloc0(sizeof (MapCacheEntry));
         pentry->next = entry;
-        xen_remap_bucket(entry, cache_size, address_index);
+        xen_remap_bucket(entry, 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);
+            xen_remap_bucket(entry, cache_size, address_index, dummy);
         }
     }
 
@@ -282,6 +302,10 @@ tryagain:
             translated = true;
             goto tryagain;
         }
+        if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
+            dummy = true;
+            goto tryagain;
+        }
         trace_xen_map_cache_return(NULL);
         return NULL;
     }
-- 
2.7.4


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

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-04 15:47 ` Igor Druzhinin
@ 2017-07-04 15:47   ` Igor Druzhinin
  -1 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: Igor Druzhinin, sstabellini, anthony.perard, paul.durrant, pbonzini

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 and maps again at the same place using
a new guest address. If the mapping is dummy this call will
make it real.

This function makes use of a new xenforeignmemory_map2() call
with an 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    | 79 ++++++++++++++++++++++++++++++++++++++-----
 include/hw/xen/xen_common.h   |  7 ++++
 include/sysemu/xen-mapcache.h | 11 +++++-
 4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -151,6 +151,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)
@@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry *entry,
     err = g_malloc0(nb_pfn * sizeof (int));
 
     if (entry->vaddr_base != NULL) {
-        ram_block_notify_remove(entry->vaddr_base, entry->size);
+        if (entry->vaddr_base != vaddr) {
+            ram_block_notify_remove(entry->vaddr_base, entry->size);
+        }
         if (munmap(entry->vaddr_base, entry->size) != 0) {
             perror("unmap fails");
             exit(-1);
@@ -181,11 +184,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);
         }
         entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
@@ -194,7 +197,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");
@@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry *entry,
         entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
     }
 
+    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
+        ram_block_notify_add(vaddr_base, size);
+    }
+
     entry->vaddr_base = vaddr_base;
     entry->paddr_index = address_index;
     entry->size = size;
     entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long) *
             BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
 
-    ram_block_notify_add(entry->vaddr_base, entry->size);
     bitmap_zero(entry->valid_mapping, nb_pfn);
     for (i = 0; i < nb_pfn; i++) {
         if (!err[i]) {
@@ -282,14 +288,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);
         }
     }
 
@@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
 
     mapcache_unlock();
 }
+
+static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
+                                                 hwaddr new_phys_addr,
+                                                 hwaddr size)
+{
+    MapCacheEntry *entry;
+    hwaddr address_index;
+    hwaddr address_offset;
+    hwaddr cache_size = size;
+    hwaddr test_bit_size;
+
+    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+    assert(size);
+    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
+    test_bit_size = size + (old_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);
+    }
+
+    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+    while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) {
+        entry = entry->next;
+    }
+    if (!entry) {
+        DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr);
+        return NULL;
+    }
+
+    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+    xen_remap_bucket(entry, entry->vaddr_base, 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;
+    }
+
+    return entry->vaddr_base + address_offset;
+}
+
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr new_phys_addr, hwaddr size)
+{
+    uint8_t *p;
+
+    mapcache_lock();
+    p = xen_replace_cache_entry_unlocked(old_phys_addr, new_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..b38962c 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
+                                 hwaddr new_phys_addr,
+                                 hwaddr size);
 #else
 
 static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
@@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
 {
 }
 
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
+                                 hwaddr new_phys_addr,
+                                 hwaddr size)
+{
+    abort();
+}
+
 #endif
 
 #endif /* XEN_MAPCACHE_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-04 15:47   ` Igor Druzhinin
  0 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: anthony.perard, Igor Druzhinin, sstabellini, paul.durrant, pbonzini

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 and maps again at the same place using
a new guest address. If the mapping is dummy this call will
make it real.

This function makes use of a new xenforeignmemory_map2() call
with an 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    | 79 ++++++++++++++++++++++++++++++++++++++-----
 include/hw/xen/xen_common.h   |  7 ++++
 include/sysemu/xen-mapcache.h | 11 +++++-
 4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -151,6 +151,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)
@@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry *entry,
     err = g_malloc0(nb_pfn * sizeof (int));
 
     if (entry->vaddr_base != NULL) {
-        ram_block_notify_remove(entry->vaddr_base, entry->size);
+        if (entry->vaddr_base != vaddr) {
+            ram_block_notify_remove(entry->vaddr_base, entry->size);
+        }
         if (munmap(entry->vaddr_base, entry->size) != 0) {
             perror("unmap fails");
             exit(-1);
@@ -181,11 +184,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);
         }
         entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
@@ -194,7 +197,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");
@@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry *entry,
         entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
     }
 
+    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
+        ram_block_notify_add(vaddr_base, size);
+    }
+
     entry->vaddr_base = vaddr_base;
     entry->paddr_index = address_index;
     entry->size = size;
     entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long) *
             BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
 
-    ram_block_notify_add(entry->vaddr_base, entry->size);
     bitmap_zero(entry->valid_mapping, nb_pfn);
     for (i = 0; i < nb_pfn; i++) {
         if (!err[i]) {
@@ -282,14 +288,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);
         }
     }
 
@@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
 
     mapcache_unlock();
 }
+
+static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
+                                                 hwaddr new_phys_addr,
+                                                 hwaddr size)
+{
+    MapCacheEntry *entry;
+    hwaddr address_index;
+    hwaddr address_offset;
+    hwaddr cache_size = size;
+    hwaddr test_bit_size;
+
+    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+    assert(size);
+    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
+    test_bit_size = size + (old_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);
+    }
+
+    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+    while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) {
+        entry = entry->next;
+    }
+    if (!entry) {
+        DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr);
+        return NULL;
+    }
+
+    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+    xen_remap_bucket(entry, entry->vaddr_base, 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;
+    }
+
+    return entry->vaddr_base + address_offset;
+}
+
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr new_phys_addr, hwaddr size)
+{
+    uint8_t *p;
+
+    mapcache_lock();
+    p = xen_replace_cache_entry_unlocked(old_phys_addr, new_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..b38962c 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
+                                 hwaddr new_phys_addr,
+                                 hwaddr size);
 #else
 
 static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
@@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
 {
 }
 
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
+                                 hwaddr new_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

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [Qemu-devel] [PATCH v2 4/4] xen: don't use xenstore to save/restore physmap anymore
  2017-07-04 15:47 ` Igor Druzhinin
@ 2017-07-04 15:47   ` Igor Druzhinin
  -1 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: Igor Druzhinin, sstabellini, anthony.perard, paul.durrant, pbonzini

If we have a system with xenforeignmemory_map2() implemented
we don't need to save/restore physmap on suspend/restore
anymore. In case we resume a VM without physmap - try to
recreate the physmap during memory region restore phase and
remap map cache entries accordingly. The old code is left
for compatibility reasons.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
 hw/i386/xen/xen-hvm.c       | 48 ++++++++++++++++++++++++++++++++++-----------
 include/hw/xen/xen_common.h |  1 +
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index d259cf7..d24ca47 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -289,6 +289,7 @@ static XenPhysmap *get_physmapping(XenIOState *state,
     return NULL;
 }
 
+#ifdef XEN_COMPAT_PHYSMAP
 static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
                                                    ram_addr_t size, void *opaque)
 {
@@ -334,6 +335,12 @@ static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
     }
     return 0;
 }
+#else
+static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
+{
+    return 0;
+}
+#endif
 
 static int xen_add_to_physmap(XenIOState *state,
                               hwaddr start_addr,
@@ -368,6 +375,26 @@ go_physmap:
     DPRINTF("mapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx"\n",
             start_addr, start_addr + size);
 
+    mr_name = memory_region_name(mr);
+
+    physmap = g_malloc(sizeof (XenPhysmap));
+
+    physmap->start_addr = start_addr;
+    physmap->size = size;
+    physmap->name = mr_name;
+    physmap->phys_offset = phys_offset;
+
+    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
+
+    if (runstate_check(RUN_STATE_INMIGRATE)) {
+        /* Now when we have a physmap entry we can replace a dummy mapping with
+         * a real one of guest foreign memory. */
+        uint8_t *p = xen_replace_cache_entry(phys_offset, start_addr, size);
+        assert(p && p == memory_region_get_ram_ptr(mr));
+
+        return 0;
+    }
+
     pfn = phys_offset >> TARGET_PAGE_BITS;
     start_gpfn = start_addr >> TARGET_PAGE_BITS;
     for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
@@ -382,17 +409,6 @@ go_physmap:
         }
     }
 
-    mr_name = memory_region_name(mr);
-
-    physmap = g_malloc(sizeof (XenPhysmap));
-
-    physmap->start_addr = start_addr;
-    physmap->size = size;
-    physmap->name = mr_name;
-    physmap->phys_offset = phys_offset;
-
-    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
-
     xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
                                    start_addr >> TARGET_PAGE_BITS,
                                    (start_addr + size - 1) >> TARGET_PAGE_BITS,
@@ -1158,6 +1174,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
     xs_daemon_close(state->xenstore);
 }
 
+#ifdef XEN_COMPAT_PHYSMAP
 static void xen_read_physmap(XenIOState *state)
 {
     XenPhysmap *physmap = NULL;
@@ -1205,6 +1222,11 @@ static void xen_read_physmap(XenIOState *state)
     }
     free(entries);
 }
+#else
+static void xen_read_physmap(XenIOState *state)
+{
+}
+#endif
 
 static void xen_wakeup_notifier(Notifier *notifier, void *data)
 {
@@ -1331,7 +1353,11 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
     state->bufioreq_local_port = rc;
 
     /* Init RAM management */
+#ifdef XEN_COMPAT_PHYSMAP
     xen_map_cache_init(xen_phys_offset_to_gaddr, state);
+#else
+    xen_map_cache_init(NULL, state);
+#endif
     xen_ram_init(pcms, ram_size, ram_memory);
 
     qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 70a5cad..c04c5c9 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -80,6 +80,7 @@ extern xenforeignmemory_handle *xen_fmem;
 
 #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
 
+#define XEN_COMPAT_PHYSMAP
 #define xenforeignmemory_map2(h, d, a, p, f, ps, ar, e) \
     xenforeignmemory_map(h, d, p, ps, ar, e)
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 4/4] xen: don't use xenstore to save/restore physmap anymore
@ 2017-07-04 15:47   ` Igor Druzhinin
  0 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 15:47 UTC (permalink / raw)
  To: xen-devel, qemu-devel
  Cc: anthony.perard, Igor Druzhinin, sstabellini, paul.durrant, pbonzini

If we have a system with xenforeignmemory_map2() implemented
we don't need to save/restore physmap on suspend/restore
anymore. In case we resume a VM without physmap - try to
recreate the physmap during memory region restore phase and
remap map cache entries accordingly. The old code is left
for compatibility reasons.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
 hw/i386/xen/xen-hvm.c       | 48 ++++++++++++++++++++++++++++++++++-----------
 include/hw/xen/xen_common.h |  1 +
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index d259cf7..d24ca47 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -289,6 +289,7 @@ static XenPhysmap *get_physmapping(XenIOState *state,
     return NULL;
 }
 
+#ifdef XEN_COMPAT_PHYSMAP
 static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
                                                    ram_addr_t size, void *opaque)
 {
@@ -334,6 +335,12 @@ static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
     }
     return 0;
 }
+#else
+static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
+{
+    return 0;
+}
+#endif
 
 static int xen_add_to_physmap(XenIOState *state,
                               hwaddr start_addr,
@@ -368,6 +375,26 @@ go_physmap:
     DPRINTF("mapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx"\n",
             start_addr, start_addr + size);
 
+    mr_name = memory_region_name(mr);
+
+    physmap = g_malloc(sizeof (XenPhysmap));
+
+    physmap->start_addr = start_addr;
+    physmap->size = size;
+    physmap->name = mr_name;
+    physmap->phys_offset = phys_offset;
+
+    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
+
+    if (runstate_check(RUN_STATE_INMIGRATE)) {
+        /* Now when we have a physmap entry we can replace a dummy mapping with
+         * a real one of guest foreign memory. */
+        uint8_t *p = xen_replace_cache_entry(phys_offset, start_addr, size);
+        assert(p && p == memory_region_get_ram_ptr(mr));
+
+        return 0;
+    }
+
     pfn = phys_offset >> TARGET_PAGE_BITS;
     start_gpfn = start_addr >> TARGET_PAGE_BITS;
     for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
@@ -382,17 +409,6 @@ go_physmap:
         }
     }
 
-    mr_name = memory_region_name(mr);
-
-    physmap = g_malloc(sizeof (XenPhysmap));
-
-    physmap->start_addr = start_addr;
-    physmap->size = size;
-    physmap->name = mr_name;
-    physmap->phys_offset = phys_offset;
-
-    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
-
     xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
                                    start_addr >> TARGET_PAGE_BITS,
                                    (start_addr + size - 1) >> TARGET_PAGE_BITS,
@@ -1158,6 +1174,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
     xs_daemon_close(state->xenstore);
 }
 
+#ifdef XEN_COMPAT_PHYSMAP
 static void xen_read_physmap(XenIOState *state)
 {
     XenPhysmap *physmap = NULL;
@@ -1205,6 +1222,11 @@ static void xen_read_physmap(XenIOState *state)
     }
     free(entries);
 }
+#else
+static void xen_read_physmap(XenIOState *state)
+{
+}
+#endif
 
 static void xen_wakeup_notifier(Notifier *notifier, void *data)
 {
@@ -1331,7 +1353,11 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
     state->bufioreq_local_port = rc;
 
     /* Init RAM management */
+#ifdef XEN_COMPAT_PHYSMAP
     xen_map_cache_init(xen_phys_offset_to_gaddr, state);
+#else
+    xen_map_cache_init(NULL, state);
+#endif
     xen_ram_init(pcms, ram_size, ram_memory);
 
     qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 70a5cad..c04c5c9 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -80,6 +80,7 @@ extern xenforeignmemory_handle *xen_fmem;
 
 #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
 
+#define XEN_COMPAT_PHYSMAP
 #define xenforeignmemory_map2(h, d, a, p, f, ps, ar, e) \
     xenforeignmemory_map(h, d, p, ps, ar, e)
 
-- 
2.7.4


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

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/4] xen: move physmap saving into a separate function
  2017-07-04 15:47   ` Igor Druzhinin
@ 2017-07-04 16:05     ` Paul Durrant
  -1 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-04 16:05 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: sstabellini, Anthony Perard, pbonzini



> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 16:48
> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> Subject: [PATCH v2 1/4] xen: move physmap saving into a separate function
> 
> Non-functional change.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Reviewed-by: Paul Durrant <paul.durrant@citrix.com>

> ---
>  hw/i386/xen/xen-hvm.c | 57 ++++++++++++++++++++++++++++------------
> -----------
>  1 file changed, 31 insertions(+), 26 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index cffa7e2..d259cf7 100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -305,6 +305,36 @@ static hwaddr xen_phys_offset_to_gaddr(hwaddr
> start_addr,
>      return start_addr;
>  }
> 
> +static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
> +{
> +    char path[80], value[17];
> +
> +    snprintf(path, sizeof(path),
> +            "/local/domain/0/device-
> model/%d/physmap/%"PRIx64"/start_addr",
> +            xen_domid, (uint64_t)physmap->phys_offset);
> +    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap-
> >start_addr);
> +    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> +        return -1;
> +    }
> +    snprintf(path, sizeof(path),
> +            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
> +            xen_domid, (uint64_t)physmap->phys_offset);
> +    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
> +    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> +        return -1;
> +    }
> +    if (physmap->name) {
> +        snprintf(path, sizeof(path),
> +                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
> +                xen_domid, (uint64_t)physmap->phys_offset);
> +        if (!xs_write(state->xenstore, 0, path,
> +                      physmap->name, strlen(physmap->name))) {
> +            return -1;
> +        }
> +    }
> +    return 0;
> +}
> +
>  static int xen_add_to_physmap(XenIOState *state,
>                                hwaddr start_addr,
>                                ram_addr_t size,
> @@ -316,7 +346,6 @@ static int xen_add_to_physmap(XenIOState *state,
>      XenPhysmap *physmap = NULL;
>      hwaddr pfn, start_gpfn;
>      hwaddr phys_offset = memory_region_get_ram_addr(mr);
> -    char path[80], value[17];
>      const char *mr_name;
> 
>      if (get_physmapping(state, start_addr, size)) {
> @@ -368,31 +397,7 @@ go_physmap:
>                                     start_addr >> TARGET_PAGE_BITS,
>                                     (start_addr + size - 1) >> TARGET_PAGE_BITS,
>                                     XEN_DOMCTL_MEM_CACHEATTR_WB);
> -
> -    snprintf(path, sizeof(path),
> -            "/local/domain/0/device-
> model/%d/physmap/%"PRIx64"/start_addr",
> -            xen_domid, (uint64_t)phys_offset);
> -    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
> -    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> -        return -1;
> -    }
> -    snprintf(path, sizeof(path),
> -            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
> -            xen_domid, (uint64_t)phys_offset);
> -    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
> -    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> -        return -1;
> -    }
> -    if (mr_name) {
> -        snprintf(path, sizeof(path),
> -                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
> -                xen_domid, (uint64_t)phys_offset);
> -        if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
> -            return -1;
> -        }
> -    }
> -
> -    return 0;
> +    return xen_save_physmap(state, physmap);
>  }
> 
>  static int xen_remove_from_physmap(XenIOState *state,
> --
> 2.7.4

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 1/4] xen: move physmap saving into a separate function
@ 2017-07-04 16:05     ` Paul Durrant
  0 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-04 16:05 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: Anthony Perard, pbonzini, sstabellini



> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 16:48
> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> Subject: [PATCH v2 1/4] xen: move physmap saving into a separate function
> 
> Non-functional change.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Reviewed-by: Paul Durrant <paul.durrant@citrix.com>

> ---
>  hw/i386/xen/xen-hvm.c | 57 ++++++++++++++++++++++++++++------------
> -----------
>  1 file changed, 31 insertions(+), 26 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index cffa7e2..d259cf7 100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -305,6 +305,36 @@ static hwaddr xen_phys_offset_to_gaddr(hwaddr
> start_addr,
>      return start_addr;
>  }
> 
> +static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
> +{
> +    char path[80], value[17];
> +
> +    snprintf(path, sizeof(path),
> +            "/local/domain/0/device-
> model/%d/physmap/%"PRIx64"/start_addr",
> +            xen_domid, (uint64_t)physmap->phys_offset);
> +    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap-
> >start_addr);
> +    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> +        return -1;
> +    }
> +    snprintf(path, sizeof(path),
> +            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
> +            xen_domid, (uint64_t)physmap->phys_offset);
> +    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
> +    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> +        return -1;
> +    }
> +    if (physmap->name) {
> +        snprintf(path, sizeof(path),
> +                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
> +                xen_domid, (uint64_t)physmap->phys_offset);
> +        if (!xs_write(state->xenstore, 0, path,
> +                      physmap->name, strlen(physmap->name))) {
> +            return -1;
> +        }
> +    }
> +    return 0;
> +}
> +
>  static int xen_add_to_physmap(XenIOState *state,
>                                hwaddr start_addr,
>                                ram_addr_t size,
> @@ -316,7 +346,6 @@ static int xen_add_to_physmap(XenIOState *state,
>      XenPhysmap *physmap = NULL;
>      hwaddr pfn, start_gpfn;
>      hwaddr phys_offset = memory_region_get_ram_addr(mr);
> -    char path[80], value[17];
>      const char *mr_name;
> 
>      if (get_physmapping(state, start_addr, size)) {
> @@ -368,31 +397,7 @@ go_physmap:
>                                     start_addr >> TARGET_PAGE_BITS,
>                                     (start_addr + size - 1) >> TARGET_PAGE_BITS,
>                                     XEN_DOMCTL_MEM_CACHEATTR_WB);
> -
> -    snprintf(path, sizeof(path),
> -            "/local/domain/0/device-
> model/%d/physmap/%"PRIx64"/start_addr",
> -            xen_domid, (uint64_t)phys_offset);
> -    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
> -    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> -        return -1;
> -    }
> -    snprintf(path, sizeof(path),
> -            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
> -            xen_domid, (uint64_t)phys_offset);
> -    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
> -    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> -        return -1;
> -    }
> -    if (mr_name) {
> -        snprintf(path, sizeof(path),
> -                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
> -                xen_domid, (uint64_t)phys_offset);
> -        if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
> -            return -1;
> -        }
> -    }
> -
> -    return 0;
> +    return xen_save_physmap(state, physmap);
>  }
> 
>  static int xen_remove_from_physmap(XenIOState *state,
> --
> 2.7.4


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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/4] xen/mapcache: add an ability to create dummy mappings
  2017-07-04 15:47   ` Igor Druzhinin
@ 2017-07-04 16:11     ` Paul Durrant
  -1 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-04 16:11 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: sstabellini, Anthony Perard, pbonzini

> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 16:48
> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> Subject: [PATCH v2 2/4] xen/mapcache: add an ability to create dummy
> mappings
> 
> Dummys are simple anonymous mappings that are placed instead
> of regular foreign mappings in certain situations when we need
> to postpone the actual mapping but still have to give a
> memory region to QEMU to play with.
> 
> This is planned to be used for restore on Xen.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Reviewed-by: Paul Durrant <paul.durrant@citrix.com>

> ---
>  hw/i386/xen/xen-mapcache.c | 40
> ++++++++++++++++++++++++++++++++--------
>  1 file changed, 32 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
> index e60156c..cd4e746 100644
> --- a/hw/i386/xen/xen-mapcache.c
> +++ b/hw/i386/xen/xen-mapcache.c
> @@ -53,6 +53,8 @@ typedef struct MapCacheEntry {
>      uint8_t *vaddr_base;
>      unsigned long *valid_mapping;
>      uint8_t lock;
> +#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
> +    uint8_t flags;
>      hwaddr size;
>      struct MapCacheEntry *next;
>  } MapCacheEntry;
> @@ -150,7 +152,8 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f,
> void *opaque)
> 
>  static void xen_remap_bucket(MapCacheEntry *entry,
>                               hwaddr size,
> -                             hwaddr address_index)
> +                             hwaddr address_index,
> +                             bool dummy)
>  {
>      uint8_t *vaddr_base;
>      xen_pfn_t *pfns;
> @@ -177,11 +180,27 @@ static void xen_remap_bucket(MapCacheEntry
> *entry,
>          pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT))
> + i;
>      }
> 
> -    vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
> PROT_READ|PROT_WRITE,
> -                                      nb_pfn, pfns, err);
> -    if (vaddr_base == NULL) {
> -        perror("xenforeignmemory_map");
> -        exit(-1);
> +    if (!dummy) {
> +        vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
> +                                           PROT_READ|PROT_WRITE,
> +                                           nb_pfn, pfns, err);
> +        if (vaddr_base == NULL) {
> +            perror("xenforeignmemory_map");
> +            exit(-1);
> +        }
> +        entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> +    } else {
> +        /*
> +         * 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,
> +                          MAP_ANON|MAP_SHARED, -1, 0);
> +        if (vaddr_base == NULL) {
> +            perror("mmap");
> +            exit(-1);
> +        }
> +        entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>      }
> 
>      entry->vaddr_base = vaddr_base;
> @@ -211,6 +230,7 @@ static uint8_t *xen_map_cache_unlocked(hwaddr
> phys_addr, hwaddr size,
>      hwaddr cache_size = size;
>      hwaddr test_bit_size;
>      bool translated = false;
> +    bool dummy = false;
> 
>  tryagain:
>      address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
> @@ -262,14 +282,14 @@ tryagain:
>      if (!entry) {
>          entry = g_malloc0(sizeof (MapCacheEntry));
>          pentry->next = entry;
> -        xen_remap_bucket(entry, cache_size, address_index);
> +        xen_remap_bucket(entry, 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);
> +            xen_remap_bucket(entry, cache_size, address_index, dummy);
>          }
>      }
> 
> @@ -282,6 +302,10 @@ tryagain:
>              translated = true;
>              goto tryagain;
>          }
> +        if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
> +            dummy = true;
> +            goto tryagain;
> +        }
>          trace_xen_map_cache_return(NULL);
>          return NULL;
>      }
> --
> 2.7.4

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 2/4] xen/mapcache: add an ability to create dummy mappings
@ 2017-07-04 16:11     ` Paul Durrant
  0 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-04 16:11 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: Anthony Perard, pbonzini, sstabellini

> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 16:48
> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> Subject: [PATCH v2 2/4] xen/mapcache: add an ability to create dummy
> mappings
> 
> Dummys are simple anonymous mappings that are placed instead
> of regular foreign mappings in certain situations when we need
> to postpone the actual mapping but still have to give a
> memory region to QEMU to play with.
> 
> This is planned to be used for restore on Xen.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Reviewed-by: Paul Durrant <paul.durrant@citrix.com>

> ---
>  hw/i386/xen/xen-mapcache.c | 40
> ++++++++++++++++++++++++++++++++--------
>  1 file changed, 32 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
> index e60156c..cd4e746 100644
> --- a/hw/i386/xen/xen-mapcache.c
> +++ b/hw/i386/xen/xen-mapcache.c
> @@ -53,6 +53,8 @@ typedef struct MapCacheEntry {
>      uint8_t *vaddr_base;
>      unsigned long *valid_mapping;
>      uint8_t lock;
> +#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
> +    uint8_t flags;
>      hwaddr size;
>      struct MapCacheEntry *next;
>  } MapCacheEntry;
> @@ -150,7 +152,8 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f,
> void *opaque)
> 
>  static void xen_remap_bucket(MapCacheEntry *entry,
>                               hwaddr size,
> -                             hwaddr address_index)
> +                             hwaddr address_index,
> +                             bool dummy)
>  {
>      uint8_t *vaddr_base;
>      xen_pfn_t *pfns;
> @@ -177,11 +180,27 @@ static void xen_remap_bucket(MapCacheEntry
> *entry,
>          pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT))
> + i;
>      }
> 
> -    vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
> PROT_READ|PROT_WRITE,
> -                                      nb_pfn, pfns, err);
> -    if (vaddr_base == NULL) {
> -        perror("xenforeignmemory_map");
> -        exit(-1);
> +    if (!dummy) {
> +        vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
> +                                           PROT_READ|PROT_WRITE,
> +                                           nb_pfn, pfns, err);
> +        if (vaddr_base == NULL) {
> +            perror("xenforeignmemory_map");
> +            exit(-1);
> +        }
> +        entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> +    } else {
> +        /*
> +         * 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,
> +                          MAP_ANON|MAP_SHARED, -1, 0);
> +        if (vaddr_base == NULL) {
> +            perror("mmap");
> +            exit(-1);
> +        }
> +        entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>      }
> 
>      entry->vaddr_base = vaddr_base;
> @@ -211,6 +230,7 @@ static uint8_t *xen_map_cache_unlocked(hwaddr
> phys_addr, hwaddr size,
>      hwaddr cache_size = size;
>      hwaddr test_bit_size;
>      bool translated = false;
> +    bool dummy = false;
> 
>  tryagain:
>      address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
> @@ -262,14 +282,14 @@ tryagain:
>      if (!entry) {
>          entry = g_malloc0(sizeof (MapCacheEntry));
>          pentry->next = entry;
> -        xen_remap_bucket(entry, cache_size, address_index);
> +        xen_remap_bucket(entry, 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);
> +            xen_remap_bucket(entry, cache_size, address_index, dummy);
>          }
>      }
> 
> @@ -282,6 +302,10 @@ tryagain:
>              translated = true;
>              goto tryagain;
>          }
> +        if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
> +            dummy = true;
> +            goto tryagain;
> +        }
>          trace_xen_map_cache_return(NULL);
>          return NULL;
>      }
> --
> 2.7.4


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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-04 15:47   ` Igor Druzhinin
@ 2017-07-04 16:27     ` Paul Durrant
  -1 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-04 16:27 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: sstabellini, Anthony Perard, pbonzini

> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 16:48
> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> Subject: [PATCH v2 3/4] xen/mapcache: introduce
> xen_replace_cache_entry()
> 
> 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 and maps again at the same place using
> a new guest address. If the mapping is dummy this call will
> make it real.
> 
> This function makes use of a new xenforeignmemory_map2() call
> with an extended interface that was recently introduced in
> libxenforeignmemory [1].

I don't understand how the compat layer works here. If xenforeignmemory_map2() is not available then you can't control the placement in virtual address space.

  Paul

> 
> [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    | 79
> ++++++++++++++++++++++++++++++++++++++-----
>  include/hw/xen/xen_common.h   |  7 ++++
>  include/sysemu/xen-mapcache.h | 11 +++++-
>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> --- a/hw/i386/xen/xen-mapcache.c
> +++ b/hw/i386/xen/xen-mapcache.c
> @@ -151,6 +151,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)
> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
> *entry,
>      err = g_malloc0(nb_pfn * sizeof (int));
> 
>      if (entry->vaddr_base != NULL) {
> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> +        if (entry->vaddr_base != vaddr) {
> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> +        }
>          if (munmap(entry->vaddr_base, entry->size) != 0) {
>              perror("unmap fails");
>              exit(-1);
> @@ -181,11 +184,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);
>          }
>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> @@ -194,7 +197,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");
> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry
> *entry,
>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>      }
> 
> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> +        ram_block_notify_add(vaddr_base, size);
> +    }
> +
>      entry->vaddr_base = vaddr_base;
>      entry->paddr_index = address_index;
>      entry->size = size;
>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long)
> *
>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> 
> -    ram_block_notify_add(entry->vaddr_base, entry->size);
>      bitmap_zero(entry->valid_mapping, nb_pfn);
>      for (i = 0; i < nb_pfn; i++) {
>          if (!err[i]) {
> @@ -282,14 +288,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);
>          }
>      }
> 
> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
> 
>      mapcache_unlock();
>  }
> +
> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
> old_phys_addr,
> +                                                 hwaddr new_phys_addr,
> +                                                 hwaddr size)
> +{
> +    MapCacheEntry *entry;
> +    hwaddr address_index;
> +    hwaddr address_offset;
> +    hwaddr cache_size = size;
> +    hwaddr test_bit_size;
> +
> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> +    assert(size);
> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> +    test_bit_size = size + (old_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);
> +    }
> +
> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
> +    while (entry && !(entry->paddr_index == address_index && entry->size
> == cache_size)) {
> +        entry = entry->next;
> +    }
> +    if (!entry) {
> +        DPRINTF("Trying to update an entry for %lx that is not in the
> mapcache!\n", phys_addr);
> +        return NULL;
> +    }
> +
> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> +    }
> +
> +    return entry->vaddr_base + address_offset;
> +}
> +
> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
> new_phys_addr, hwaddr size)
> +{
> +    uint8_t *p;
> +
> +    mapcache_lock();
> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
> new_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..b38962c 100644
> --- a/include/sysemu/xen-mapcache.h
> +++ b/include/sysemu/xen-mapcache.h
> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> +                                 hwaddr new_phys_addr,
> +                                 hwaddr size);
>  #else
> 
>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
>  {
>  }
> 
> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> +                                 hwaddr new_phys_addr,
> +                                 hwaddr size)
> +{
> +    abort();
> +}
> +
>  #endif
> 
>  #endif /* XEN_MAPCACHE_H */
> --
> 2.7.4

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-04 16:27     ` Paul Durrant
  0 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-04 16:27 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: Anthony Perard, pbonzini, sstabellini

> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 16:48
> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> Subject: [PATCH v2 3/4] xen/mapcache: introduce
> xen_replace_cache_entry()
> 
> 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 and maps again at the same place using
> a new guest address. If the mapping is dummy this call will
> make it real.
> 
> This function makes use of a new xenforeignmemory_map2() call
> with an extended interface that was recently introduced in
> libxenforeignmemory [1].

I don't understand how the compat layer works here. If xenforeignmemory_map2() is not available then you can't control the placement in virtual address space.

  Paul

> 
> [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    | 79
> ++++++++++++++++++++++++++++++++++++++-----
>  include/hw/xen/xen_common.h   |  7 ++++
>  include/sysemu/xen-mapcache.h | 11 +++++-
>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> --- a/hw/i386/xen/xen-mapcache.c
> +++ b/hw/i386/xen/xen-mapcache.c
> @@ -151,6 +151,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)
> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
> *entry,
>      err = g_malloc0(nb_pfn * sizeof (int));
> 
>      if (entry->vaddr_base != NULL) {
> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> +        if (entry->vaddr_base != vaddr) {
> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> +        }
>          if (munmap(entry->vaddr_base, entry->size) != 0) {
>              perror("unmap fails");
>              exit(-1);
> @@ -181,11 +184,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);
>          }
>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> @@ -194,7 +197,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");
> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry
> *entry,
>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>      }
> 
> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> +        ram_block_notify_add(vaddr_base, size);
> +    }
> +
>      entry->vaddr_base = vaddr_base;
>      entry->paddr_index = address_index;
>      entry->size = size;
>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long)
> *
>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> 
> -    ram_block_notify_add(entry->vaddr_base, entry->size);
>      bitmap_zero(entry->valid_mapping, nb_pfn);
>      for (i = 0; i < nb_pfn; i++) {
>          if (!err[i]) {
> @@ -282,14 +288,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);
>          }
>      }
> 
> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
> 
>      mapcache_unlock();
>  }
> +
> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
> old_phys_addr,
> +                                                 hwaddr new_phys_addr,
> +                                                 hwaddr size)
> +{
> +    MapCacheEntry *entry;
> +    hwaddr address_index;
> +    hwaddr address_offset;
> +    hwaddr cache_size = size;
> +    hwaddr test_bit_size;
> +
> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> +    assert(size);
> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> +    test_bit_size = size + (old_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);
> +    }
> +
> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
> +    while (entry && !(entry->paddr_index == address_index && entry->size
> == cache_size)) {
> +        entry = entry->next;
> +    }
> +    if (!entry) {
> +        DPRINTF("Trying to update an entry for %lx that is not in the
> mapcache!\n", phys_addr);
> +        return NULL;
> +    }
> +
> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> +    }
> +
> +    return entry->vaddr_base + address_offset;
> +}
> +
> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
> new_phys_addr, hwaddr size)
> +{
> +    uint8_t *p;
> +
> +    mapcache_lock();
> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
> new_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..b38962c 100644
> --- a/include/sysemu/xen-mapcache.h
> +++ b/include/sysemu/xen-mapcache.h
> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> +                                 hwaddr new_phys_addr,
> +                                 hwaddr size);
>  #else
> 
>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
>  {
>  }
> 
> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> +                                 hwaddr new_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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-04 16:27     ` Paul Durrant
@ 2017-07-04 16:34       ` Igor Druzhinin
  -1 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 16:34 UTC (permalink / raw)
  To: Paul Durrant, xen-devel, qemu-devel; +Cc: sstabellini, Anthony Perard, pbonzini

On 04/07/17 17:27, Paul Durrant wrote:
>> -----Original Message-----
>> From: Igor Druzhinin
>> Sent: 04 July 2017 16:48
>> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
>> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
>> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
>> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
>> Subject: [PATCH v2 3/4] xen/mapcache: introduce
>> xen_replace_cache_entry()
>>
>> 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 and maps again at the same place using
>> a new guest address. If the mapping is dummy this call will
>> make it real.
>>
>> This function makes use of a new xenforeignmemory_map2() call
>> with an extended interface that was recently introduced in
>> libxenforeignmemory [1].
> 
> I don't understand how the compat layer works here. If xenforeignmemory_map2() is not available then you can't control the placement in virtual address space.
> 

If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
going to be defined as xenforeignmemory_map(). At the same time
XEN_COMPAT_PHYSMAP is defined and the entry replace function (which
relies on xenforeignmemory_map2 functionality) is never going to be called.

If you mean that I should incorporate this into the description I can do it.

Igor

>   Paul
> 
>>
>> [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    | 79
>> ++++++++++++++++++++++++++++++++++++++-----
>>  include/hw/xen/xen_common.h   |  7 ++++
>>  include/sysemu/xen-mapcache.h | 11 +++++-
>>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
>> --- a/hw/i386/xen/xen-mapcache.c
>> +++ b/hw/i386/xen/xen-mapcache.c
>> @@ -151,6 +151,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)
>> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
>> *entry,
>>      err = g_malloc0(nb_pfn * sizeof (int));
>>
>>      if (entry->vaddr_base != NULL) {
>> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
>> +        if (entry->vaddr_base != vaddr) {
>> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
>> +        }
>>          if (munmap(entry->vaddr_base, entry->size) != 0) {
>>              perror("unmap fails");
>>              exit(-1);
>> @@ -181,11 +184,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);
>>          }
>>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
>> @@ -194,7 +197,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");
>> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry
>> *entry,
>>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>>      }
>>
>> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
>> +        ram_block_notify_add(vaddr_base, size);
>> +    }
>> +
>>      entry->vaddr_base = vaddr_base;
>>      entry->paddr_index = address_index;
>>      entry->size = size;
>>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long)
>> *
>>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
>>
>> -    ram_block_notify_add(entry->vaddr_base, entry->size);
>>      bitmap_zero(entry->valid_mapping, nb_pfn);
>>      for (i = 0; i < nb_pfn; i++) {
>>          if (!err[i]) {
>> @@ -282,14 +288,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);
>>          }
>>      }
>>
>> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
>>
>>      mapcache_unlock();
>>  }
>> +
>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
>> old_phys_addr,
>> +                                                 hwaddr new_phys_addr,
>> +                                                 hwaddr size)
>> +{
>> +    MapCacheEntry *entry;
>> +    hwaddr address_index;
>> +    hwaddr address_offset;
>> +    hwaddr cache_size = size;
>> +    hwaddr test_bit_size;
>> +
>> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
>> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>> +
>> +    assert(size);
>> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
>> +    test_bit_size = size + (old_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);
>> +    }
>> +
>> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
>> +    while (entry && !(entry->paddr_index == address_index && entry->size
>> == cache_size)) {
>> +        entry = entry->next;
>> +    }
>> +    if (!entry) {
>> +        DPRINTF("Trying to update an entry for %lx that is not in the
>> mapcache!\n", phys_addr);
>> +        return NULL;
>> +    }
>> +
>> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
>> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>> +
>> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
>> +    }
>> +
>> +    return entry->vaddr_base + address_offset;
>> +}
>> +
>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
>> new_phys_addr, hwaddr size)
>> +{
>> +    uint8_t *p;
>> +
>> +    mapcache_lock();
>> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
>> new_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..b38962c 100644
>> --- a/include/sysemu/xen-mapcache.h
>> +++ b/include/sysemu/xen-mapcache.h
>> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
>> +                                 hwaddr new_phys_addr,
>> +                                 hwaddr size);
>>  #else
>>
>>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
>> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
>>  {
>>  }
>>
>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
>> +                                 hwaddr new_phys_addr,
>> +                                 hwaddr size)
>> +{
>> +    abort();
>> +}
>> +
>>  #endif
>>
>>  #endif /* XEN_MAPCACHE_H */
>> --
>> 2.7.4
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-04 16:34       ` Igor Druzhinin
  0 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 16:34 UTC (permalink / raw)
  To: Paul Durrant, xen-devel, qemu-devel; +Cc: Anthony Perard, pbonzini, sstabellini

On 04/07/17 17:27, Paul Durrant wrote:
>> -----Original Message-----
>> From: Igor Druzhinin
>> Sent: 04 July 2017 16:48
>> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
>> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
>> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
>> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
>> Subject: [PATCH v2 3/4] xen/mapcache: introduce
>> xen_replace_cache_entry()
>>
>> 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 and maps again at the same place using
>> a new guest address. If the mapping is dummy this call will
>> make it real.
>>
>> This function makes use of a new xenforeignmemory_map2() call
>> with an extended interface that was recently introduced in
>> libxenforeignmemory [1].
> 
> I don't understand how the compat layer works here. If xenforeignmemory_map2() is not available then you can't control the placement in virtual address space.
> 

If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
going to be defined as xenforeignmemory_map(). At the same time
XEN_COMPAT_PHYSMAP is defined and the entry replace function (which
relies on xenforeignmemory_map2 functionality) is never going to be called.

If you mean that I should incorporate this into the description I can do it.

Igor

>   Paul
> 
>>
>> [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    | 79
>> ++++++++++++++++++++++++++++++++++++++-----
>>  include/hw/xen/xen_common.h   |  7 ++++
>>  include/sysemu/xen-mapcache.h | 11 +++++-
>>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
>> --- a/hw/i386/xen/xen-mapcache.c
>> +++ b/hw/i386/xen/xen-mapcache.c
>> @@ -151,6 +151,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)
>> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
>> *entry,
>>      err = g_malloc0(nb_pfn * sizeof (int));
>>
>>      if (entry->vaddr_base != NULL) {
>> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
>> +        if (entry->vaddr_base != vaddr) {
>> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
>> +        }
>>          if (munmap(entry->vaddr_base, entry->size) != 0) {
>>              perror("unmap fails");
>>              exit(-1);
>> @@ -181,11 +184,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);
>>          }
>>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
>> @@ -194,7 +197,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");
>> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry
>> *entry,
>>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>>      }
>>
>> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
>> +        ram_block_notify_add(vaddr_base, size);
>> +    }
>> +
>>      entry->vaddr_base = vaddr_base;
>>      entry->paddr_index = address_index;
>>      entry->size = size;
>>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long)
>> *
>>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
>>
>> -    ram_block_notify_add(entry->vaddr_base, entry->size);
>>      bitmap_zero(entry->valid_mapping, nb_pfn);
>>      for (i = 0; i < nb_pfn; i++) {
>>          if (!err[i]) {
>> @@ -282,14 +288,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);
>>          }
>>      }
>>
>> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
>>
>>      mapcache_unlock();
>>  }
>> +
>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
>> old_phys_addr,
>> +                                                 hwaddr new_phys_addr,
>> +                                                 hwaddr size)
>> +{
>> +    MapCacheEntry *entry;
>> +    hwaddr address_index;
>> +    hwaddr address_offset;
>> +    hwaddr cache_size = size;
>> +    hwaddr test_bit_size;
>> +
>> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
>> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>> +
>> +    assert(size);
>> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
>> +    test_bit_size = size + (old_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);
>> +    }
>> +
>> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
>> +    while (entry && !(entry->paddr_index == address_index && entry->size
>> == cache_size)) {
>> +        entry = entry->next;
>> +    }
>> +    if (!entry) {
>> +        DPRINTF("Trying to update an entry for %lx that is not in the
>> mapcache!\n", phys_addr);
>> +        return NULL;
>> +    }
>> +
>> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
>> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>> +
>> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
>> +    }
>> +
>> +    return entry->vaddr_base + address_offset;
>> +}
>> +
>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
>> new_phys_addr, hwaddr size)
>> +{
>> +    uint8_t *p;
>> +
>> +    mapcache_lock();
>> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
>> new_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..b38962c 100644
>> --- a/include/sysemu/xen-mapcache.h
>> +++ b/include/sysemu/xen-mapcache.h
>> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
>> +                                 hwaddr new_phys_addr,
>> +                                 hwaddr size);
>>  #else
>>
>>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
>> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
>>  {
>>  }
>>
>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
>> +                                 hwaddr new_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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-04 16:34       ` Igor Druzhinin
@ 2017-07-04 16:42         ` Paul Durrant
  -1 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-04 16:42 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: sstabellini, Anthony Perard, pbonzini

> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 17:34
> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
> qemu-devel@nongnu.org
> Cc: sstabellini@kernel.org; Anthony Perard <anthony.perard@citrix.com>;
> pbonzini@redhat.com
> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> xen_replace_cache_entry()
> 
> On 04/07/17 17:27, Paul Durrant wrote:
> >> -----Original Message-----
> >> From: Igor Druzhinin
> >> Sent: 04 July 2017 16:48
> >> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> >> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> >> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> >> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> >> Subject: [PATCH v2 3/4] xen/mapcache: introduce
> >> xen_replace_cache_entry()
> >>
> >> 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 and maps again at the same place using
> >> a new guest address. If the mapping is dummy this call will
> >> make it real.
> >>
> >> This function makes use of a new xenforeignmemory_map2() call
> >> with an extended interface that was recently introduced in
> >> libxenforeignmemory [1].
> >
> > I don't understand how the compat layer works here. If
> xenforeignmemory_map2() is not available then you can't control the
> placement in virtual address space.
> >
> 
> If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
> going to be defined as xenforeignmemory_map(). At the same time
> XEN_COMPAT_PHYSMAP is defined and the entry replace function (which
> relies on xenforeignmemory_map2 functionality) is never going to be called.
> 
> If you mean that I should incorporate this into the description I can do it.

AFAICT XEN_COMPAT_PHYSMAP is not introduced until patch #4 though.

The problem really comes down to defining xenforeignmemory_map2() in terms of xenforeignmemory_map(). It basically can't be safely done. Could you define xenforeignmemory_map2() as abort() in the compat case instead? 

  Paul

> 
> Igor
> 
> >   Paul
> >
> >>
> >> [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    | 79
> >> ++++++++++++++++++++++++++++++++++++++-----
> >>  include/hw/xen/xen_common.h   |  7 ++++
> >>  include/sysemu/xen-mapcache.h | 11 +++++-
> >>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> >> --- a/hw/i386/xen/xen-mapcache.c
> >> +++ b/hw/i386/xen/xen-mapcache.c
> >> @@ -151,6 +151,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)
> >> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
> >> *entry,
> >>      err = g_malloc0(nb_pfn * sizeof (int));
> >>
> >>      if (entry->vaddr_base != NULL) {
> >> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> >> +        if (entry->vaddr_base != vaddr) {
> >> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> >> +        }
> >>          if (munmap(entry->vaddr_base, entry->size) != 0) {
> >>              perror("unmap fails");
> >>              exit(-1);
> >> @@ -181,11 +184,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);
> >>          }
> >>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> >> @@ -194,7 +197,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");
> >> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry
> >> *entry,
> >>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
> >>      }
> >>
> >> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> >> +        ram_block_notify_add(vaddr_base, size);
> >> +    }
> >> +
> >>      entry->vaddr_base = vaddr_base;
> >>      entry->paddr_index = address_index;
> >>      entry->size = size;
> >>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned
> long)
> >> *
> >>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> >>
> >> -    ram_block_notify_add(entry->vaddr_base, entry->size);
> >>      bitmap_zero(entry->valid_mapping, nb_pfn);
> >>      for (i = 0; i < nb_pfn; i++) {
> >>          if (!err[i]) {
> >> @@ -282,14 +288,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);
> >>          }
> >>      }
> >>
> >> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
> >>
> >>      mapcache_unlock();
> >>  }
> >> +
> >> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
> >> old_phys_addr,
> >> +                                                 hwaddr new_phys_addr,
> >> +                                                 hwaddr size)
> >> +{
> >> +    MapCacheEntry *entry;
> >> +    hwaddr address_index;
> >> +    hwaddr address_offset;
> >> +    hwaddr cache_size = size;
> >> +    hwaddr test_bit_size;
> >> +
> >> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> >> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> >> +
> >> +    assert(size);
> >> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> >> +    test_bit_size = size + (old_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);
> >> +    }
> >> +
> >> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
> >> +    while (entry && !(entry->paddr_index == address_index && entry-
> >size
> >> == cache_size)) {
> >> +        entry = entry->next;
> >> +    }
> >> +    if (!entry) {
> >> +        DPRINTF("Trying to update an entry for %lx that is not in the
> >> mapcache!\n", phys_addr);
> >> +        return NULL;
> >> +    }
> >> +
> >> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> >> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> >> +
> >> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> >> +    }
> >> +
> >> +    return entry->vaddr_base + address_offset;
> >> +}
> >> +
> >> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
> >> new_phys_addr, hwaddr size)
> >> +{
> >> +    uint8_t *p;
> >> +
> >> +    mapcache_lock();
> >> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
> >> new_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..b38962c 100644
> >> --- a/include/sysemu/xen-mapcache.h
> >> +++ b/include/sysemu/xen-mapcache.h
> >> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> >> +                                 hwaddr new_phys_addr,
> >> +                                 hwaddr size);
> >>  #else
> >>
> >>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> >> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
> >>  {
> >>  }
> >>
> >> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> >> +                                 hwaddr new_phys_addr,
> >> +                                 hwaddr size)
> >> +{
> >> +    abort();
> >> +}
> >> +
> >>  #endif
> >>
> >>  #endif /* XEN_MAPCACHE_H */
> >> --
> >> 2.7.4
> >

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-04 16:42         ` Paul Durrant
  0 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-04 16:42 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: Anthony Perard, pbonzini, sstabellini

> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 17:34
> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
> qemu-devel@nongnu.org
> Cc: sstabellini@kernel.org; Anthony Perard <anthony.perard@citrix.com>;
> pbonzini@redhat.com
> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> xen_replace_cache_entry()
> 
> On 04/07/17 17:27, Paul Durrant wrote:
> >> -----Original Message-----
> >> From: Igor Druzhinin
> >> Sent: 04 July 2017 16:48
> >> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> >> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> >> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> >> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> >> Subject: [PATCH v2 3/4] xen/mapcache: introduce
> >> xen_replace_cache_entry()
> >>
> >> 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 and maps again at the same place using
> >> a new guest address. If the mapping is dummy this call will
> >> make it real.
> >>
> >> This function makes use of a new xenforeignmemory_map2() call
> >> with an extended interface that was recently introduced in
> >> libxenforeignmemory [1].
> >
> > I don't understand how the compat layer works here. If
> xenforeignmemory_map2() is not available then you can't control the
> placement in virtual address space.
> >
> 
> If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
> going to be defined as xenforeignmemory_map(). At the same time
> XEN_COMPAT_PHYSMAP is defined and the entry replace function (which
> relies on xenforeignmemory_map2 functionality) is never going to be called.
> 
> If you mean that I should incorporate this into the description I can do it.

AFAICT XEN_COMPAT_PHYSMAP is not introduced until patch #4 though.

The problem really comes down to defining xenforeignmemory_map2() in terms of xenforeignmemory_map(). It basically can't be safely done. Could you define xenforeignmemory_map2() as abort() in the compat case instead? 

  Paul

> 
> Igor
> 
> >   Paul
> >
> >>
> >> [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    | 79
> >> ++++++++++++++++++++++++++++++++++++++-----
> >>  include/hw/xen/xen_common.h   |  7 ++++
> >>  include/sysemu/xen-mapcache.h | 11 +++++-
> >>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> >> --- a/hw/i386/xen/xen-mapcache.c
> >> +++ b/hw/i386/xen/xen-mapcache.c
> >> @@ -151,6 +151,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)
> >> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
> >> *entry,
> >>      err = g_malloc0(nb_pfn * sizeof (int));
> >>
> >>      if (entry->vaddr_base != NULL) {
> >> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> >> +        if (entry->vaddr_base != vaddr) {
> >> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> >> +        }
> >>          if (munmap(entry->vaddr_base, entry->size) != 0) {
> >>              perror("unmap fails");
> >>              exit(-1);
> >> @@ -181,11 +184,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);
> >>          }
> >>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> >> @@ -194,7 +197,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");
> >> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry
> >> *entry,
> >>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
> >>      }
> >>
> >> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> >> +        ram_block_notify_add(vaddr_base, size);
> >> +    }
> >> +
> >>      entry->vaddr_base = vaddr_base;
> >>      entry->paddr_index = address_index;
> >>      entry->size = size;
> >>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned
> long)
> >> *
> >>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> >>
> >> -    ram_block_notify_add(entry->vaddr_base, entry->size);
> >>      bitmap_zero(entry->valid_mapping, nb_pfn);
> >>      for (i = 0; i < nb_pfn; i++) {
> >>          if (!err[i]) {
> >> @@ -282,14 +288,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);
> >>          }
> >>      }
> >>
> >> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
> >>
> >>      mapcache_unlock();
> >>  }
> >> +
> >> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
> >> old_phys_addr,
> >> +                                                 hwaddr new_phys_addr,
> >> +                                                 hwaddr size)
> >> +{
> >> +    MapCacheEntry *entry;
> >> +    hwaddr address_index;
> >> +    hwaddr address_offset;
> >> +    hwaddr cache_size = size;
> >> +    hwaddr test_bit_size;
> >> +
> >> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> >> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> >> +
> >> +    assert(size);
> >> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> >> +    test_bit_size = size + (old_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);
> >> +    }
> >> +
> >> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
> >> +    while (entry && !(entry->paddr_index == address_index && entry-
> >size
> >> == cache_size)) {
> >> +        entry = entry->next;
> >> +    }
> >> +    if (!entry) {
> >> +        DPRINTF("Trying to update an entry for %lx that is not in the
> >> mapcache!\n", phys_addr);
> >> +        return NULL;
> >> +    }
> >> +
> >> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> >> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> >> +
> >> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> >> +    }
> >> +
> >> +    return entry->vaddr_base + address_offset;
> >> +}
> >> +
> >> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
> >> new_phys_addr, hwaddr size)
> >> +{
> >> +    uint8_t *p;
> >> +
> >> +    mapcache_lock();
> >> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
> >> new_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..b38962c 100644
> >> --- a/include/sysemu/xen-mapcache.h
> >> +++ b/include/sysemu/xen-mapcache.h
> >> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> >> +                                 hwaddr new_phys_addr,
> >> +                                 hwaddr size);
> >>  #else
> >>
> >>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> >> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
> >>  {
> >>  }
> >>
> >> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> >> +                                 hwaddr new_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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-04 16:42         ` Paul Durrant
@ 2017-07-04 16:46           ` Igor Druzhinin
  -1 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 16:46 UTC (permalink / raw)
  To: Paul Durrant, xen-devel, qemu-devel; +Cc: sstabellini, Anthony Perard, pbonzini

On 04/07/17 17:42, Paul Durrant wrote:
>> -----Original Message-----
>> From: Igor Druzhinin
>> Sent: 04 July 2017 17:34
>> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
>> qemu-devel@nongnu.org
>> Cc: sstabellini@kernel.org; Anthony Perard <anthony.perard@citrix.com>;
>> pbonzini@redhat.com
>> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
>> xen_replace_cache_entry()
>>
>> On 04/07/17 17:27, Paul Durrant wrote:
>>>> -----Original Message-----
>>>> From: Igor Druzhinin
>>>> Sent: 04 July 2017 16:48
>>>> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
>>>> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
>>>> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
>>>> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
>>>> Subject: [PATCH v2 3/4] xen/mapcache: introduce
>>>> xen_replace_cache_entry()
>>>>
>>>> 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 and maps again at the same place using
>>>> a new guest address. If the mapping is dummy this call will
>>>> make it real.
>>>>
>>>> This function makes use of a new xenforeignmemory_map2() call
>>>> with an extended interface that was recently introduced in
>>>> libxenforeignmemory [1].
>>>
>>> I don't understand how the compat layer works here. If
>> xenforeignmemory_map2() is not available then you can't control the
>> placement in virtual address space.
>>>
>>
>> If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
>> going to be defined as xenforeignmemory_map(). At the same time
>> XEN_COMPAT_PHYSMAP is defined and the entry replace function (which
>> relies on xenforeignmemory_map2 functionality) is never going to be called.
>>
>> If you mean that I should incorporate this into the description I can do it.
> 
> AFAICT XEN_COMPAT_PHYSMAP is not introduced until patch #4 though.
> 
> The problem really comes down to defining xenforeignmemory_map2() in terms of xenforeignmemory_map(). It basically can't be safely done. Could you define xenforeignmemory_map2() as abort() in the compat case instead? 
>

xen_replace_cache_entry() is not called in patch #3. Which means it's
safe to use a fallback version (xenforeignmemory_map) in
xen_remap_bucket here.

Igor

>   Paul
> 
>>
>> Igor
>>
>>>   Paul
>>>
>>>>
>>>> [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    | 79
>>>> ++++++++++++++++++++++++++++++++++++++-----
>>>>  include/hw/xen/xen_common.h   |  7 ++++
>>>>  include/sysemu/xen-mapcache.h | 11 +++++-
>>>>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
>>>> --- a/hw/i386/xen/xen-mapcache.c
>>>> +++ b/hw/i386/xen/xen-mapcache.c
>>>> @@ -151,6 +151,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)
>>>> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
>>>> *entry,
>>>>      err = g_malloc0(nb_pfn * sizeof (int));
>>>>
>>>>      if (entry->vaddr_base != NULL) {
>>>> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
>>>> +        if (entry->vaddr_base != vaddr) {
>>>> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
>>>> +        }
>>>>          if (munmap(entry->vaddr_base, entry->size) != 0) {
>>>>              perror("unmap fails");
>>>>              exit(-1);
>>>> @@ -181,11 +184,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);
>>>>          }
>>>>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
>>>> @@ -194,7 +197,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");
>>>> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry
>>>> *entry,
>>>>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>>>>      }
>>>>
>>>> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
>>>> +        ram_block_notify_add(vaddr_base, size);
>>>> +    }
>>>> +
>>>>      entry->vaddr_base = vaddr_base;
>>>>      entry->paddr_index = address_index;
>>>>      entry->size = size;
>>>>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned
>> long)
>>>> *
>>>>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
>>>>
>>>> -    ram_block_notify_add(entry->vaddr_base, entry->size);
>>>>      bitmap_zero(entry->valid_mapping, nb_pfn);
>>>>      for (i = 0; i < nb_pfn; i++) {
>>>>          if (!err[i]) {
>>>> @@ -282,14 +288,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);
>>>>          }
>>>>      }
>>>>
>>>> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
>>>>
>>>>      mapcache_unlock();
>>>>  }
>>>> +
>>>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
>>>> old_phys_addr,
>>>> +                                                 hwaddr new_phys_addr,
>>>> +                                                 hwaddr size)
>>>> +{
>>>> +    MapCacheEntry *entry;
>>>> +    hwaddr address_index;
>>>> +    hwaddr address_offset;
>>>> +    hwaddr cache_size = size;
>>>> +    hwaddr test_bit_size;
>>>> +
>>>> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
>>>> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>>>> +
>>>> +    assert(size);
>>>> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
>>>> +    test_bit_size = size + (old_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);
>>>> +    }
>>>> +
>>>> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
>>>> +    while (entry && !(entry->paddr_index == address_index && entry-
>>> size
>>>> == cache_size)) {
>>>> +        entry = entry->next;
>>>> +    }
>>>> +    if (!entry) {
>>>> +        DPRINTF("Trying to update an entry for %lx that is not in the
>>>> mapcache!\n", phys_addr);
>>>> +        return NULL;
>>>> +    }
>>>> +
>>>> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
>>>> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>>>> +
>>>> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
>>>> +    }
>>>> +
>>>> +    return entry->vaddr_base + address_offset;
>>>> +}
>>>> +
>>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
>>>> new_phys_addr, hwaddr size)
>>>> +{
>>>> +    uint8_t *p;
>>>> +
>>>> +    mapcache_lock();
>>>> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
>>>> new_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..b38962c 100644
>>>> --- a/include/sysemu/xen-mapcache.h
>>>> +++ b/include/sysemu/xen-mapcache.h
>>>> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
>>>> +                                 hwaddr new_phys_addr,
>>>> +                                 hwaddr size);
>>>>  #else
>>>>
>>>>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
>>>> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
>>>>  {
>>>>  }
>>>>
>>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
>>>> +                                 hwaddr new_phys_addr,
>>>> +                                 hwaddr size)
>>>> +{
>>>> +    abort();
>>>> +}
>>>> +
>>>>  #endif
>>>>
>>>>  #endif /* XEN_MAPCACHE_H */
>>>> --
>>>> 2.7.4
>>>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-04 16:46           ` Igor Druzhinin
  0 siblings, 0 replies; 38+ messages in thread
From: Igor Druzhinin @ 2017-07-04 16:46 UTC (permalink / raw)
  To: Paul Durrant, xen-devel, qemu-devel; +Cc: Anthony Perard, pbonzini, sstabellini

On 04/07/17 17:42, Paul Durrant wrote:
>> -----Original Message-----
>> From: Igor Druzhinin
>> Sent: 04 July 2017 17:34
>> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
>> qemu-devel@nongnu.org
>> Cc: sstabellini@kernel.org; Anthony Perard <anthony.perard@citrix.com>;
>> pbonzini@redhat.com
>> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
>> xen_replace_cache_entry()
>>
>> On 04/07/17 17:27, Paul Durrant wrote:
>>>> -----Original Message-----
>>>> From: Igor Druzhinin
>>>> Sent: 04 July 2017 16:48
>>>> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
>>>> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
>>>> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
>>>> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
>>>> Subject: [PATCH v2 3/4] xen/mapcache: introduce
>>>> xen_replace_cache_entry()
>>>>
>>>> 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 and maps again at the same place using
>>>> a new guest address. If the mapping is dummy this call will
>>>> make it real.
>>>>
>>>> This function makes use of a new xenforeignmemory_map2() call
>>>> with an extended interface that was recently introduced in
>>>> libxenforeignmemory [1].
>>>
>>> I don't understand how the compat layer works here. If
>> xenforeignmemory_map2() is not available then you can't control the
>> placement in virtual address space.
>>>
>>
>> If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
>> going to be defined as xenforeignmemory_map(). At the same time
>> XEN_COMPAT_PHYSMAP is defined and the entry replace function (which
>> relies on xenforeignmemory_map2 functionality) is never going to be called.
>>
>> If you mean that I should incorporate this into the description I can do it.
> 
> AFAICT XEN_COMPAT_PHYSMAP is not introduced until patch #4 though.
> 
> The problem really comes down to defining xenforeignmemory_map2() in terms of xenforeignmemory_map(). It basically can't be safely done. Could you define xenforeignmemory_map2() as abort() in the compat case instead? 
>

xen_replace_cache_entry() is not called in patch #3. Which means it's
safe to use a fallback version (xenforeignmemory_map) in
xen_remap_bucket here.

Igor

>   Paul
> 
>>
>> Igor
>>
>>>   Paul
>>>
>>>>
>>>> [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    | 79
>>>> ++++++++++++++++++++++++++++++++++++++-----
>>>>  include/hw/xen/xen_common.h   |  7 ++++
>>>>  include/sysemu/xen-mapcache.h | 11 +++++-
>>>>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
>>>> --- a/hw/i386/xen/xen-mapcache.c
>>>> +++ b/hw/i386/xen/xen-mapcache.c
>>>> @@ -151,6 +151,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)
>>>> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
>>>> *entry,
>>>>      err = g_malloc0(nb_pfn * sizeof (int));
>>>>
>>>>      if (entry->vaddr_base != NULL) {
>>>> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
>>>> +        if (entry->vaddr_base != vaddr) {
>>>> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
>>>> +        }
>>>>          if (munmap(entry->vaddr_base, entry->size) != 0) {
>>>>              perror("unmap fails");
>>>>              exit(-1);
>>>> @@ -181,11 +184,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);
>>>>          }
>>>>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
>>>> @@ -194,7 +197,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");
>>>> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry
>>>> *entry,
>>>>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>>>>      }
>>>>
>>>> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
>>>> +        ram_block_notify_add(vaddr_base, size);
>>>> +    }
>>>> +
>>>>      entry->vaddr_base = vaddr_base;
>>>>      entry->paddr_index = address_index;
>>>>      entry->size = size;
>>>>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned
>> long)
>>>> *
>>>>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
>>>>
>>>> -    ram_block_notify_add(entry->vaddr_base, entry->size);
>>>>      bitmap_zero(entry->valid_mapping, nb_pfn);
>>>>      for (i = 0; i < nb_pfn; i++) {
>>>>          if (!err[i]) {
>>>> @@ -282,14 +288,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);
>>>>          }
>>>>      }
>>>>
>>>> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
>>>>
>>>>      mapcache_unlock();
>>>>  }
>>>> +
>>>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
>>>> old_phys_addr,
>>>> +                                                 hwaddr new_phys_addr,
>>>> +                                                 hwaddr size)
>>>> +{
>>>> +    MapCacheEntry *entry;
>>>> +    hwaddr address_index;
>>>> +    hwaddr address_offset;
>>>> +    hwaddr cache_size = size;
>>>> +    hwaddr test_bit_size;
>>>> +
>>>> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
>>>> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>>>> +
>>>> +    assert(size);
>>>> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
>>>> +    test_bit_size = size + (old_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);
>>>> +    }
>>>> +
>>>> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
>>>> +    while (entry && !(entry->paddr_index == address_index && entry-
>>> size
>>>> == cache_size)) {
>>>> +        entry = entry->next;
>>>> +    }
>>>> +    if (!entry) {
>>>> +        DPRINTF("Trying to update an entry for %lx that is not in the
>>>> mapcache!\n", phys_addr);
>>>> +        return NULL;
>>>> +    }
>>>> +
>>>> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
>>>> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>>>> +
>>>> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
>>>> +    }
>>>> +
>>>> +    return entry->vaddr_base + address_offset;
>>>> +}
>>>> +
>>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
>>>> new_phys_addr, hwaddr size)
>>>> +{
>>>> +    uint8_t *p;
>>>> +
>>>> +    mapcache_lock();
>>>> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
>>>> new_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..b38962c 100644
>>>> --- a/include/sysemu/xen-mapcache.h
>>>> +++ b/include/sysemu/xen-mapcache.h
>>>> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
>>>> +                                 hwaddr new_phys_addr,
>>>> +                                 hwaddr size);
>>>>  #else
>>>>
>>>>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
>>>> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
>>>>  {
>>>>  }
>>>>
>>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
>>>> +                                 hwaddr new_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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-04 16:46           ` Igor Druzhinin
@ 2017-07-05  8:52             ` Paul Durrant
  -1 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-05  8:52 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: sstabellini, Anthony Perard, pbonzini

> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 17:47
> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
> qemu-devel@nongnu.org
> Cc: sstabellini@kernel.org; Anthony Perard <anthony.perard@citrix.com>;
> pbonzini@redhat.com
> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> xen_replace_cache_entry()
> 
> On 04/07/17 17:42, Paul Durrant wrote:
> >> -----Original Message-----
> >> From: Igor Druzhinin
> >> Sent: 04 July 2017 17:34
> >> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-
> devel@lists.xenproject.org;
> >> qemu-devel@nongnu.org
> >> Cc: sstabellini@kernel.org; Anthony Perard
> <anthony.perard@citrix.com>;
> >> pbonzini@redhat.com
> >> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> >> xen_replace_cache_entry()
> >>
> >> On 04/07/17 17:27, Paul Durrant wrote:
> >>>> -----Original Message-----
> >>>> From: Igor Druzhinin
> >>>> Sent: 04 July 2017 16:48
> >>>> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> >>>> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> >>>> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> >>>> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> >>>> Subject: [PATCH v2 3/4] xen/mapcache: introduce
> >>>> xen_replace_cache_entry()
> >>>>
> >>>> 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 and maps again at the same place using
> >>>> a new guest address. If the mapping is dummy this call will
> >>>> make it real.
> >>>>
> >>>> This function makes use of a new xenforeignmemory_map2() call
> >>>> with an extended interface that was recently introduced in
> >>>> libxenforeignmemory [1].
> >>>
> >>> I don't understand how the compat layer works here. If
> >> xenforeignmemory_map2() is not available then you can't control the
> >> placement in virtual address space.
> >>>
> >>
> >> If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
> >> going to be defined as xenforeignmemory_map(). At the same time
> >> XEN_COMPAT_PHYSMAP is defined and the entry replace function
> (which
> >> relies on xenforeignmemory_map2 functionality) is never going to be
> called.
> >>
> >> If you mean that I should incorporate this into the description I can do it.
> >
> > AFAICT XEN_COMPAT_PHYSMAP is not introduced until patch #4 though.
> >
> > The problem really comes down to defining xenforeignmemory_map2() in
> terms of xenforeignmemory_map(). It basically can't be safely done. Could
> you define xenforeignmemory_map2() as abort() in the compat case
> instead?
> >
> 
> xen_replace_cache_entry() is not called in patch #3. Which means it's
> safe to use a fallback version (xenforeignmemory_map) in
> xen_remap_bucket here.

I still don't like the fact that the compat definition of xenforeignmemory_map2() loses the extra argument. That's going to catch someone out one day. Is there any way you could re-work it so that xenforeignmemory_map() is uses in the cases where the memory placement does not matter?

  Paul

> 
> Igor
> 
> >   Paul
> >
> >>
> >> Igor
> >>
> >>>   Paul
> >>>
> >>>>
> >>>> [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    | 79
> >>>> ++++++++++++++++++++++++++++++++++++++-----
> >>>>  include/hw/xen/xen_common.h   |  7 ++++
> >>>>  include/sysemu/xen-mapcache.h | 11 +++++-
> >>>>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> >>>> --- a/hw/i386/xen/xen-mapcache.c
> >>>> +++ b/hw/i386/xen/xen-mapcache.c
> >>>> @@ -151,6 +151,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)
> >>>> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
> >>>> *entry,
> >>>>      err = g_malloc0(nb_pfn * sizeof (int));
> >>>>
> >>>>      if (entry->vaddr_base != NULL) {
> >>>> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> >>>> +        if (entry->vaddr_base != vaddr) {
> >>>> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> >>>> +        }
> >>>>          if (munmap(entry->vaddr_base, entry->size) != 0) {
> >>>>              perror("unmap fails");
> >>>>              exit(-1);
> >>>> @@ -181,11 +184,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);
> >>>>          }
> >>>>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> >>>> @@ -194,7 +197,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");
> >>>> @@ -203,13 +206,16 @@ static void
> xen_remap_bucket(MapCacheEntry
> >>>> *entry,
> >>>>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
> >>>>      }
> >>>>
> >>>> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> >>>> +        ram_block_notify_add(vaddr_base, size);
> >>>> +    }
> >>>> +
> >>>>      entry->vaddr_base = vaddr_base;
> >>>>      entry->paddr_index = address_index;
> >>>>      entry->size = size;
> >>>>      entry->valid_mapping = (unsigned long *)
> g_malloc0(sizeof(unsigned
> >> long)
> >>>> *
> >>>>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> >>>>
> >>>> -    ram_block_notify_add(entry->vaddr_base, entry->size);
> >>>>      bitmap_zero(entry->valid_mapping, nb_pfn);
> >>>>      for (i = 0; i < nb_pfn; i++) {
> >>>>          if (!err[i]) {
> >>>> @@ -282,14 +288,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);
> >>>>          }
> >>>>      }
> >>>>
> >>>> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
> >>>>
> >>>>      mapcache_unlock();
> >>>>  }
> >>>> +
> >>>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
> >>>> old_phys_addr,
> >>>> +                                                 hwaddr new_phys_addr,
> >>>> +                                                 hwaddr size)
> >>>> +{
> >>>> +    MapCacheEntry *entry;
> >>>> +    hwaddr address_index;
> >>>> +    hwaddr address_offset;
> >>>> +    hwaddr cache_size = size;
> >>>> +    hwaddr test_bit_size;
> >>>> +
> >>>> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> >>>> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> >>>> +
> >>>> +    assert(size);
> >>>> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> >>>> +    test_bit_size = size + (old_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);
> >>>> +    }
> >>>> +
> >>>> +    entry = &mapcache->entry[address_index % mapcache-
> >nr_buckets];
> >>>> +    while (entry && !(entry->paddr_index == address_index && entry-
> >>> size
> >>>> == cache_size)) {
> >>>> +        entry = entry->next;
> >>>> +    }
> >>>> +    if (!entry) {
> >>>> +        DPRINTF("Trying to update an entry for %lx that is not in the
> >>>> mapcache!\n", phys_addr);
> >>>> +        return NULL;
> >>>> +    }
> >>>> +
> >>>> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> >>>> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> >>>> +
> >>>> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> >>>> +    }
> >>>> +
> >>>> +    return entry->vaddr_base + address_offset;
> >>>> +}
> >>>> +
> >>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
> >>>> new_phys_addr, hwaddr size)
> >>>> +{
> >>>> +    uint8_t *p;
> >>>> +
> >>>> +    mapcache_lock();
> >>>> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
> >>>> new_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..b38962c 100644
> >>>> --- a/include/sysemu/xen-mapcache.h
> >>>> +++ b/include/sysemu/xen-mapcache.h
> >>>> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> >>>> +                                 hwaddr new_phys_addr,
> >>>> +                                 hwaddr size);
> >>>>  #else
> >>>>
> >>>>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> >>>> @@ -50,6 +52,13 @@ static inline void
> xen_invalidate_map_cache(void)
> >>>>  {
> >>>>  }
> >>>>
> >>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> >>>> +                                 hwaddr new_phys_addr,
> >>>> +                                 hwaddr size)
> >>>> +{
> >>>> +    abort();
> >>>> +}
> >>>> +
> >>>>  #endif
> >>>>
> >>>>  #endif /* XEN_MAPCACHE_H */
> >>>> --
> >>>> 2.7.4
> >>>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-05  8:52             ` Paul Durrant
  0 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-05  8:52 UTC (permalink / raw)
  To: Igor Druzhinin, xen-devel, qemu-devel
  Cc: Anthony Perard, pbonzini, sstabellini

> -----Original Message-----
> From: Igor Druzhinin
> Sent: 04 July 2017 17:47
> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
> qemu-devel@nongnu.org
> Cc: sstabellini@kernel.org; Anthony Perard <anthony.perard@citrix.com>;
> pbonzini@redhat.com
> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> xen_replace_cache_entry()
> 
> On 04/07/17 17:42, Paul Durrant wrote:
> >> -----Original Message-----
> >> From: Igor Druzhinin
> >> Sent: 04 July 2017 17:34
> >> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-
> devel@lists.xenproject.org;
> >> qemu-devel@nongnu.org
> >> Cc: sstabellini@kernel.org; Anthony Perard
> <anthony.perard@citrix.com>;
> >> pbonzini@redhat.com
> >> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> >> xen_replace_cache_entry()
> >>
> >> On 04/07/17 17:27, Paul Durrant wrote:
> >>>> -----Original Message-----
> >>>> From: Igor Druzhinin
> >>>> Sent: 04 July 2017 16:48
> >>>> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> >>>> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> >>>> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> >>>> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> >>>> Subject: [PATCH v2 3/4] xen/mapcache: introduce
> >>>> xen_replace_cache_entry()
> >>>>
> >>>> 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 and maps again at the same place using
> >>>> a new guest address. If the mapping is dummy this call will
> >>>> make it real.
> >>>>
> >>>> This function makes use of a new xenforeignmemory_map2() call
> >>>> with an extended interface that was recently introduced in
> >>>> libxenforeignmemory [1].
> >>>
> >>> I don't understand how the compat layer works here. If
> >> xenforeignmemory_map2() is not available then you can't control the
> >> placement in virtual address space.
> >>>
> >>
> >> If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
> >> going to be defined as xenforeignmemory_map(). At the same time
> >> XEN_COMPAT_PHYSMAP is defined and the entry replace function
> (which
> >> relies on xenforeignmemory_map2 functionality) is never going to be
> called.
> >>
> >> If you mean that I should incorporate this into the description I can do it.
> >
> > AFAICT XEN_COMPAT_PHYSMAP is not introduced until patch #4 though.
> >
> > The problem really comes down to defining xenforeignmemory_map2() in
> terms of xenforeignmemory_map(). It basically can't be safely done. Could
> you define xenforeignmemory_map2() as abort() in the compat case
> instead?
> >
> 
> xen_replace_cache_entry() is not called in patch #3. Which means it's
> safe to use a fallback version (xenforeignmemory_map) in
> xen_remap_bucket here.

I still don't like the fact that the compat definition of xenforeignmemory_map2() loses the extra argument. That's going to catch someone out one day. Is there any way you could re-work it so that xenforeignmemory_map() is uses in the cases where the memory placement does not matter?

  Paul

> 
> Igor
> 
> >   Paul
> >
> >>
> >> Igor
> >>
> >>>   Paul
> >>>
> >>>>
> >>>> [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    | 79
> >>>> ++++++++++++++++++++++++++++++++++++++-----
> >>>>  include/hw/xen/xen_common.h   |  7 ++++
> >>>>  include/sysemu/xen-mapcache.h | 11 +++++-
> >>>>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> >>>> --- a/hw/i386/xen/xen-mapcache.c
> >>>> +++ b/hw/i386/xen/xen-mapcache.c
> >>>> @@ -151,6 +151,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)
> >>>> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
> >>>> *entry,
> >>>>      err = g_malloc0(nb_pfn * sizeof (int));
> >>>>
> >>>>      if (entry->vaddr_base != NULL) {
> >>>> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> >>>> +        if (entry->vaddr_base != vaddr) {
> >>>> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> >>>> +        }
> >>>>          if (munmap(entry->vaddr_base, entry->size) != 0) {
> >>>>              perror("unmap fails");
> >>>>              exit(-1);
> >>>> @@ -181,11 +184,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);
> >>>>          }
> >>>>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> >>>> @@ -194,7 +197,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");
> >>>> @@ -203,13 +206,16 @@ static void
> xen_remap_bucket(MapCacheEntry
> >>>> *entry,
> >>>>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
> >>>>      }
> >>>>
> >>>> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> >>>> +        ram_block_notify_add(vaddr_base, size);
> >>>> +    }
> >>>> +
> >>>>      entry->vaddr_base = vaddr_base;
> >>>>      entry->paddr_index = address_index;
> >>>>      entry->size = size;
> >>>>      entry->valid_mapping = (unsigned long *)
> g_malloc0(sizeof(unsigned
> >> long)
> >>>> *
> >>>>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> >>>>
> >>>> -    ram_block_notify_add(entry->vaddr_base, entry->size);
> >>>>      bitmap_zero(entry->valid_mapping, nb_pfn);
> >>>>      for (i = 0; i < nb_pfn; i++) {
> >>>>          if (!err[i]) {
> >>>> @@ -282,14 +288,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);
> >>>>          }
> >>>>      }
> >>>>
> >>>> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
> >>>>
> >>>>      mapcache_unlock();
> >>>>  }
> >>>> +
> >>>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
> >>>> old_phys_addr,
> >>>> +                                                 hwaddr new_phys_addr,
> >>>> +                                                 hwaddr size)
> >>>> +{
> >>>> +    MapCacheEntry *entry;
> >>>> +    hwaddr address_index;
> >>>> +    hwaddr address_offset;
> >>>> +    hwaddr cache_size = size;
> >>>> +    hwaddr test_bit_size;
> >>>> +
> >>>> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> >>>> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> >>>> +
> >>>> +    assert(size);
> >>>> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> >>>> +    test_bit_size = size + (old_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);
> >>>> +    }
> >>>> +
> >>>> +    entry = &mapcache->entry[address_index % mapcache-
> >nr_buckets];
> >>>> +    while (entry && !(entry->paddr_index == address_index && entry-
> >>> size
> >>>> == cache_size)) {
> >>>> +        entry = entry->next;
> >>>> +    }
> >>>> +    if (!entry) {
> >>>> +        DPRINTF("Trying to update an entry for %lx that is not in the
> >>>> mapcache!\n", phys_addr);
> >>>> +        return NULL;
> >>>> +    }
> >>>> +
> >>>> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> >>>> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> >>>> +
> >>>> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> >>>> +    }
> >>>> +
> >>>> +    return entry->vaddr_base + address_offset;
> >>>> +}
> >>>> +
> >>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
> >>>> new_phys_addr, hwaddr size)
> >>>> +{
> >>>> +    uint8_t *p;
> >>>> +
> >>>> +    mapcache_lock();
> >>>> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
> >>>> new_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..b38962c 100644
> >>>> --- a/include/sysemu/xen-mapcache.h
> >>>> +++ b/include/sysemu/xen-mapcache.h
> >>>> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> >>>> +                                 hwaddr new_phys_addr,
> >>>> +                                 hwaddr size);
> >>>>  #else
> >>>>
> >>>>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> >>>> @@ -50,6 +52,13 @@ static inline void
> xen_invalidate_map_cache(void)
> >>>>  {
> >>>>  }
> >>>>
> >>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> >>>> +                                 hwaddr new_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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/4] xen: move physmap saving into a separate function
  2017-07-04 15:47   ` Igor Druzhinin
@ 2017-07-05 22:16     ` Stefano Stabellini
  -1 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:16 UTC (permalink / raw)
  To: Igor Druzhinin
  Cc: xen-devel, qemu-devel, sstabellini, anthony.perard, paul.durrant,
	pbonzini

On Tue, 4 Jul 2017, Igor Druzhinin wrote:
> Non-functional change.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Unless you change something from a previous version, please retain the
acked-by and reviewed-by that were given (see
alpine.DEB.2.10.1706301629170.2919@sstabellini-ThinkPad-X260).


> ---
>  hw/i386/xen/xen-hvm.c | 57 ++++++++++++++++++++++++++++-----------------------
>  1 file changed, 31 insertions(+), 26 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index cffa7e2..d259cf7 100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -305,6 +305,36 @@ static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
>      return start_addr;
>  }
>  
> +static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
> +{
> +    char path[80], value[17];
> +
> +    snprintf(path, sizeof(path),
> +            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
> +            xen_domid, (uint64_t)physmap->phys_offset);
> +    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->start_addr);
> +    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> +        return -1;
> +    }
> +    snprintf(path, sizeof(path),
> +            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
> +            xen_domid, (uint64_t)physmap->phys_offset);
> +    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
> +    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> +        return -1;
> +    }
> +    if (physmap->name) {
> +        snprintf(path, sizeof(path),
> +                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
> +                xen_domid, (uint64_t)physmap->phys_offset);
> +        if (!xs_write(state->xenstore, 0, path,
> +                      physmap->name, strlen(physmap->name))) {
> +            return -1;
> +        }
> +    }
> +    return 0;
> +}
> +
>  static int xen_add_to_physmap(XenIOState *state,
>                                hwaddr start_addr,
>                                ram_addr_t size,
> @@ -316,7 +346,6 @@ static int xen_add_to_physmap(XenIOState *state,
>      XenPhysmap *physmap = NULL;
>      hwaddr pfn, start_gpfn;
>      hwaddr phys_offset = memory_region_get_ram_addr(mr);
> -    char path[80], value[17];
>      const char *mr_name;
>  
>      if (get_physmapping(state, start_addr, size)) {
> @@ -368,31 +397,7 @@ go_physmap:
>                                     start_addr >> TARGET_PAGE_BITS,
>                                     (start_addr + size - 1) >> TARGET_PAGE_BITS,
>                                     XEN_DOMCTL_MEM_CACHEATTR_WB);
> -
> -    snprintf(path, sizeof(path),
> -            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
> -            xen_domid, (uint64_t)phys_offset);
> -    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
> -    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> -        return -1;
> -    }
> -    snprintf(path, sizeof(path),
> -            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
> -            xen_domid, (uint64_t)phys_offset);
> -    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
> -    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> -        return -1;
> -    }
> -    if (mr_name) {
> -        snprintf(path, sizeof(path),
> -                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
> -                xen_domid, (uint64_t)phys_offset);
> -        if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
> -            return -1;
> -        }
> -    }
> -
> -    return 0;
> +    return xen_save_physmap(state, physmap);
>  }
>  
>  static int xen_remove_from_physmap(XenIOState *state,
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 1/4] xen: move physmap saving into a separate function
@ 2017-07-05 22:16     ` Stefano Stabellini
  0 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:16 UTC (permalink / raw)
  To: Igor Druzhinin
  Cc: sstabellini, qemu-devel, paul.durrant, pbonzini, anthony.perard,
	xen-devel

On Tue, 4 Jul 2017, Igor Druzhinin wrote:
> Non-functional change.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Unless you change something from a previous version, please retain the
acked-by and reviewed-by that were given (see
alpine.DEB.2.10.1706301629170.2919@sstabellini-ThinkPad-X260).


> ---
>  hw/i386/xen/xen-hvm.c | 57 ++++++++++++++++++++++++++++-----------------------
>  1 file changed, 31 insertions(+), 26 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index cffa7e2..d259cf7 100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -305,6 +305,36 @@ static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
>      return start_addr;
>  }
>  
> +static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
> +{
> +    char path[80], value[17];
> +
> +    snprintf(path, sizeof(path),
> +            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
> +            xen_domid, (uint64_t)physmap->phys_offset);
> +    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->start_addr);
> +    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> +        return -1;
> +    }
> +    snprintf(path, sizeof(path),
> +            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
> +            xen_domid, (uint64_t)physmap->phys_offset);
> +    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
> +    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> +        return -1;
> +    }
> +    if (physmap->name) {
> +        snprintf(path, sizeof(path),
> +                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
> +                xen_domid, (uint64_t)physmap->phys_offset);
> +        if (!xs_write(state->xenstore, 0, path,
> +                      physmap->name, strlen(physmap->name))) {
> +            return -1;
> +        }
> +    }
> +    return 0;
> +}
> +
>  static int xen_add_to_physmap(XenIOState *state,
>                                hwaddr start_addr,
>                                ram_addr_t size,
> @@ -316,7 +346,6 @@ static int xen_add_to_physmap(XenIOState *state,
>      XenPhysmap *physmap = NULL;
>      hwaddr pfn, start_gpfn;
>      hwaddr phys_offset = memory_region_get_ram_addr(mr);
> -    char path[80], value[17];
>      const char *mr_name;
>  
>      if (get_physmapping(state, start_addr, size)) {
> @@ -368,31 +397,7 @@ go_physmap:
>                                     start_addr >> TARGET_PAGE_BITS,
>                                     (start_addr + size - 1) >> TARGET_PAGE_BITS,
>                                     XEN_DOMCTL_MEM_CACHEATTR_WB);
> -
> -    snprintf(path, sizeof(path),
> -            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
> -            xen_domid, (uint64_t)phys_offset);
> -    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
> -    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> -        return -1;
> -    }
> -    snprintf(path, sizeof(path),
> -            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
> -            xen_domid, (uint64_t)phys_offset);
> -    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
> -    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
> -        return -1;
> -    }
> -    if (mr_name) {
> -        snprintf(path, sizeof(path),
> -                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
> -                xen_domid, (uint64_t)phys_offset);
> -        if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
> -            return -1;
> -        }
> -    }
> -
> -    return 0;
> +    return xen_save_physmap(state, physmap);
>  }
>  
>  static int xen_remove_from_physmap(XenIOState *state,
> -- 
> 2.7.4
> 

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/4] xen/mapcache: add an ability to create dummy mappings
  2017-07-04 15:47   ` Igor Druzhinin
@ 2017-07-05 22:38     ` Stefano Stabellini
  -1 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:38 UTC (permalink / raw)
  To: Igor Druzhinin
  Cc: xen-devel, qemu-devel, sstabellini, anthony.perard, paul.durrant,
	pbonzini

On Tue, 4 Jul 2017, Igor Druzhinin wrote:
> Dummys are simple anonymous mappings that are placed instead
> of regular foreign mappings in certain situations when we need
> to postpone the actual mapping but still have to give a
> memory region to QEMU to play with.
> 
> This is planned to be used for restore on Xen.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>


> ---
>  hw/i386/xen/xen-mapcache.c | 40 ++++++++++++++++++++++++++++++++--------
>  1 file changed, 32 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
> index e60156c..cd4e746 100644
> --- a/hw/i386/xen/xen-mapcache.c
> +++ b/hw/i386/xen/xen-mapcache.c
> @@ -53,6 +53,8 @@ typedef struct MapCacheEntry {
>      uint8_t *vaddr_base;
>      unsigned long *valid_mapping;
>      uint8_t lock;
> +#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
> +    uint8_t flags;
>      hwaddr size;
>      struct MapCacheEntry *next;
>  } MapCacheEntry;
> @@ -150,7 +152,8 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
>  
>  static void xen_remap_bucket(MapCacheEntry *entry,
>                               hwaddr size,
> -                             hwaddr address_index)
> +                             hwaddr address_index,
> +                             bool dummy)
>  {
>      uint8_t *vaddr_base;
>      xen_pfn_t *pfns;
> @@ -177,11 +180,27 @@ static void xen_remap_bucket(MapCacheEntry *entry,
>          pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
>      }
>  
> -    vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
> -                                      nb_pfn, pfns, err);
> -    if (vaddr_base == NULL) {
> -        perror("xenforeignmemory_map");
> -        exit(-1);
> +    if (!dummy) {
> +        vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
> +                                           PROT_READ|PROT_WRITE,
> +                                           nb_pfn, pfns, err);
> +        if (vaddr_base == NULL) {
> +            perror("xenforeignmemory_map");
> +            exit(-1);
> +        }
> +        entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> +    } else {
> +        /*
> +         * 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,
> +                          MAP_ANON|MAP_SHARED, -1, 0);
> +        if (vaddr_base == NULL) {
> +            perror("mmap");
> +            exit(-1);
> +        }
> +        entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>      }
>  
>      entry->vaddr_base = vaddr_base;
> @@ -211,6 +230,7 @@ static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
>      hwaddr cache_size = size;
>      hwaddr test_bit_size;
>      bool translated = false;
> +    bool dummy = false;
>  
>  tryagain:
>      address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
> @@ -262,14 +282,14 @@ tryagain:
>      if (!entry) {
>          entry = g_malloc0(sizeof (MapCacheEntry));
>          pentry->next = entry;
> -        xen_remap_bucket(entry, cache_size, address_index);
> +        xen_remap_bucket(entry, 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);
> +            xen_remap_bucket(entry, cache_size, address_index, dummy);
>          }
>      }
>  
> @@ -282,6 +302,10 @@ tryagain:
>              translated = true;
>              goto tryagain;
>          }
> +        if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
> +            dummy = true;
> +            goto tryagain;
> +        }
>          trace_xen_map_cache_return(NULL);
>          return NULL;
>      }
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 2/4] xen/mapcache: add an ability to create dummy mappings
@ 2017-07-05 22:38     ` Stefano Stabellini
  0 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:38 UTC (permalink / raw)
  To: Igor Druzhinin
  Cc: sstabellini, qemu-devel, paul.durrant, pbonzini, anthony.perard,
	xen-devel

On Tue, 4 Jul 2017, Igor Druzhinin wrote:
> Dummys are simple anonymous mappings that are placed instead
> of regular foreign mappings in certain situations when we need
> to postpone the actual mapping but still have to give a
> memory region to QEMU to play with.
> 
> This is planned to be used for restore on Xen.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>


> ---
>  hw/i386/xen/xen-mapcache.c | 40 ++++++++++++++++++++++++++++++++--------
>  1 file changed, 32 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
> index e60156c..cd4e746 100644
> --- a/hw/i386/xen/xen-mapcache.c
> +++ b/hw/i386/xen/xen-mapcache.c
> @@ -53,6 +53,8 @@ typedef struct MapCacheEntry {
>      uint8_t *vaddr_base;
>      unsigned long *valid_mapping;
>      uint8_t lock;
> +#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
> +    uint8_t flags;
>      hwaddr size;
>      struct MapCacheEntry *next;
>  } MapCacheEntry;
> @@ -150,7 +152,8 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
>  
>  static void xen_remap_bucket(MapCacheEntry *entry,
>                               hwaddr size,
> -                             hwaddr address_index)
> +                             hwaddr address_index,
> +                             bool dummy)
>  {
>      uint8_t *vaddr_base;
>      xen_pfn_t *pfns;
> @@ -177,11 +180,27 @@ static void xen_remap_bucket(MapCacheEntry *entry,
>          pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
>      }
>  
> -    vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
> -                                      nb_pfn, pfns, err);
> -    if (vaddr_base == NULL) {
> -        perror("xenforeignmemory_map");
> -        exit(-1);
> +    if (!dummy) {
> +        vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
> +                                           PROT_READ|PROT_WRITE,
> +                                           nb_pfn, pfns, err);
> +        if (vaddr_base == NULL) {
> +            perror("xenforeignmemory_map");
> +            exit(-1);
> +        }
> +        entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> +    } else {
> +        /*
> +         * 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,
> +                          MAP_ANON|MAP_SHARED, -1, 0);
> +        if (vaddr_base == NULL) {
> +            perror("mmap");
> +            exit(-1);
> +        }
> +        entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>      }
>  
>      entry->vaddr_base = vaddr_base;
> @@ -211,6 +230,7 @@ static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
>      hwaddr cache_size = size;
>      hwaddr test_bit_size;
>      bool translated = false;
> +    bool dummy = false;
>  
>  tryagain:
>      address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
> @@ -262,14 +282,14 @@ tryagain:
>      if (!entry) {
>          entry = g_malloc0(sizeof (MapCacheEntry));
>          pentry->next = entry;
> -        xen_remap_bucket(entry, cache_size, address_index);
> +        xen_remap_bucket(entry, 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);
> +            xen_remap_bucket(entry, cache_size, address_index, dummy);
>          }
>      }
>  
> @@ -282,6 +302,10 @@ tryagain:
>              translated = true;
>              goto tryagain;
>          }
> +        if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
> +            dummy = true;
> +            goto tryagain;
> +        }
>          trace_xen_map_cache_return(NULL);
>          return NULL;
>      }
> -- 
> 2.7.4
> 

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 4/4] xen: don't use xenstore to save/restore physmap anymore
  2017-07-04 15:47   ` Igor Druzhinin
@ 2017-07-05 22:38     ` Stefano Stabellini
  -1 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:38 UTC (permalink / raw)
  To: Igor Druzhinin
  Cc: xen-devel, qemu-devel, sstabellini, anthony.perard, paul.durrant,
	pbonzini

On Tue, 4 Jul 2017, Igor Druzhinin wrote:
> If we have a system with xenforeignmemory_map2() implemented
> we don't need to save/restore physmap on suspend/restore
> anymore. In case we resume a VM without physmap - try to
> recreate the physmap during memory region restore phase and
> remap map cache entries accordingly. The old code is left
> for compatibility reasons.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
> ---
>  hw/i386/xen/xen-hvm.c       | 48 ++++++++++++++++++++++++++++++++++-----------
>  include/hw/xen/xen_common.h |  1 +
>  2 files changed, 38 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index d259cf7..d24ca47 100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -289,6 +289,7 @@ static XenPhysmap *get_physmapping(XenIOState *state,
>      return NULL;
>  }
>  
> +#ifdef XEN_COMPAT_PHYSMAP
>  static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
>                                                     ram_addr_t size, void *opaque)
>  {
> @@ -334,6 +335,12 @@ static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
>      }
>      return 0;
>  }
> +#else
> +static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
> +{
> +    return 0;
> +}
> +#endif
>  
>  static int xen_add_to_physmap(XenIOState *state,
>                                hwaddr start_addr,
> @@ -368,6 +375,26 @@ go_physmap:
>      DPRINTF("mapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx"\n",
>              start_addr, start_addr + size);
>  
> +    mr_name = memory_region_name(mr);
> +
> +    physmap = g_malloc(sizeof (XenPhysmap));
> +
> +    physmap->start_addr = start_addr;
> +    physmap->size = size;
> +    physmap->name = mr_name;
> +    physmap->phys_offset = phys_offset;
> +
> +    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
> +
> +    if (runstate_check(RUN_STATE_INMIGRATE)) {
> +        /* Now when we have a physmap entry we can replace a dummy mapping with
> +         * a real one of guest foreign memory. */
> +        uint8_t *p = xen_replace_cache_entry(phys_offset, start_addr, size);
> +        assert(p && p == memory_region_get_ram_ptr(mr));
> +
> +        return 0;
> +    }
> +
>      pfn = phys_offset >> TARGET_PAGE_BITS;
>      start_gpfn = start_addr >> TARGET_PAGE_BITS;
>      for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
> @@ -382,17 +409,6 @@ go_physmap:
>          }
>      }
>  
> -    mr_name = memory_region_name(mr);
> -
> -    physmap = g_malloc(sizeof (XenPhysmap));
> -
> -    physmap->start_addr = start_addr;
> -    physmap->size = size;
> -    physmap->name = mr_name;
> -    physmap->phys_offset = phys_offset;
> -
> -    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
> -
>      xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
>                                     start_addr >> TARGET_PAGE_BITS,
>                                     (start_addr + size - 1) >> TARGET_PAGE_BITS,
> @@ -1158,6 +1174,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
>      xs_daemon_close(state->xenstore);
>  }
>  
> +#ifdef XEN_COMPAT_PHYSMAP
>  static void xen_read_physmap(XenIOState *state)
>  {
>      XenPhysmap *physmap = NULL;
> @@ -1205,6 +1222,11 @@ static void xen_read_physmap(XenIOState *state)
>      }
>      free(entries);
>  }
> +#else
> +static void xen_read_physmap(XenIOState *state)
> +{
> +}
> +#endif
>  
>  static void xen_wakeup_notifier(Notifier *notifier, void *data)
>  {
> @@ -1331,7 +1353,11 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
>      state->bufioreq_local_port = rc;
>  
>      /* Init RAM management */
> +#ifdef XEN_COMPAT_PHYSMAP
>      xen_map_cache_init(xen_phys_offset_to_gaddr, state);
> +#else
> +    xen_map_cache_init(NULL, state);
> +#endif

This is good. I would also like to #ifdef the

  if (!translated && mapcache->phys_offset_to_gaddr) {

block in xen_map_cache_unlocked


>      xen_ram_init(pcms, ram_size, ram_memory);
>  
>      qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
> diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
> index 70a5cad..c04c5c9 100644
> --- a/include/hw/xen/xen_common.h
> +++ b/include/hw/xen/xen_common.h
> @@ -80,6 +80,7 @@ extern xenforeignmemory_handle *xen_fmem;
>  
>  #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
>  
> +#define XEN_COMPAT_PHYSMAP
>  #define xenforeignmemory_map2(h, d, a, p, f, ps, ar, e) \
>      xenforeignmemory_map(h, d, p, ps, ar, e)
>  
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 4/4] xen: don't use xenstore to save/restore physmap anymore
@ 2017-07-05 22:38     ` Stefano Stabellini
  0 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:38 UTC (permalink / raw)
  To: Igor Druzhinin
  Cc: sstabellini, qemu-devel, paul.durrant, pbonzini, anthony.perard,
	xen-devel

On Tue, 4 Jul 2017, Igor Druzhinin wrote:
> If we have a system with xenforeignmemory_map2() implemented
> we don't need to save/restore physmap on suspend/restore
> anymore. In case we resume a VM without physmap - try to
> recreate the physmap during memory region restore phase and
> remap map cache entries accordingly. The old code is left
> for compatibility reasons.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
> ---
>  hw/i386/xen/xen-hvm.c       | 48 ++++++++++++++++++++++++++++++++++-----------
>  include/hw/xen/xen_common.h |  1 +
>  2 files changed, 38 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index d259cf7..d24ca47 100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -289,6 +289,7 @@ static XenPhysmap *get_physmapping(XenIOState *state,
>      return NULL;
>  }
>  
> +#ifdef XEN_COMPAT_PHYSMAP
>  static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
>                                                     ram_addr_t size, void *opaque)
>  {
> @@ -334,6 +335,12 @@ static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
>      }
>      return 0;
>  }
> +#else
> +static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
> +{
> +    return 0;
> +}
> +#endif
>  
>  static int xen_add_to_physmap(XenIOState *state,
>                                hwaddr start_addr,
> @@ -368,6 +375,26 @@ go_physmap:
>      DPRINTF("mapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx"\n",
>              start_addr, start_addr + size);
>  
> +    mr_name = memory_region_name(mr);
> +
> +    physmap = g_malloc(sizeof (XenPhysmap));
> +
> +    physmap->start_addr = start_addr;
> +    physmap->size = size;
> +    physmap->name = mr_name;
> +    physmap->phys_offset = phys_offset;
> +
> +    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
> +
> +    if (runstate_check(RUN_STATE_INMIGRATE)) {
> +        /* Now when we have a physmap entry we can replace a dummy mapping with
> +         * a real one of guest foreign memory. */
> +        uint8_t *p = xen_replace_cache_entry(phys_offset, start_addr, size);
> +        assert(p && p == memory_region_get_ram_ptr(mr));
> +
> +        return 0;
> +    }
> +
>      pfn = phys_offset >> TARGET_PAGE_BITS;
>      start_gpfn = start_addr >> TARGET_PAGE_BITS;
>      for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
> @@ -382,17 +409,6 @@ go_physmap:
>          }
>      }
>  
> -    mr_name = memory_region_name(mr);
> -
> -    physmap = g_malloc(sizeof (XenPhysmap));
> -
> -    physmap->start_addr = start_addr;
> -    physmap->size = size;
> -    physmap->name = mr_name;
> -    physmap->phys_offset = phys_offset;
> -
> -    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
> -
>      xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
>                                     start_addr >> TARGET_PAGE_BITS,
>                                     (start_addr + size - 1) >> TARGET_PAGE_BITS,
> @@ -1158,6 +1174,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
>      xs_daemon_close(state->xenstore);
>  }
>  
> +#ifdef XEN_COMPAT_PHYSMAP
>  static void xen_read_physmap(XenIOState *state)
>  {
>      XenPhysmap *physmap = NULL;
> @@ -1205,6 +1222,11 @@ static void xen_read_physmap(XenIOState *state)
>      }
>      free(entries);
>  }
> +#else
> +static void xen_read_physmap(XenIOState *state)
> +{
> +}
> +#endif
>  
>  static void xen_wakeup_notifier(Notifier *notifier, void *data)
>  {
> @@ -1331,7 +1353,11 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
>      state->bufioreq_local_port = rc;
>  
>      /* Init RAM management */
> +#ifdef XEN_COMPAT_PHYSMAP
>      xen_map_cache_init(xen_phys_offset_to_gaddr, state);
> +#else
> +    xen_map_cache_init(NULL, state);
> +#endif

This is good. I would also like to #ifdef the

  if (!translated && mapcache->phys_offset_to_gaddr) {

block in xen_map_cache_unlocked


>      xen_ram_init(pcms, ram_size, ram_memory);
>  
>      qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
> diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
> index 70a5cad..c04c5c9 100644
> --- a/include/hw/xen/xen_common.h
> +++ b/include/hw/xen/xen_common.h
> @@ -80,6 +80,7 @@ extern xenforeignmemory_handle *xen_fmem;
>  
>  #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
>  
> +#define XEN_COMPAT_PHYSMAP
>  #define xenforeignmemory_map2(h, d, a, p, f, ps, ar, e) \
>      xenforeignmemory_map(h, d, p, ps, ar, e)
>  
> -- 
> 2.7.4
> 

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-04 15:47   ` Igor Druzhinin
@ 2017-07-05 22:38     ` Stefano Stabellini
  -1 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:38 UTC (permalink / raw)
  To: Igor Druzhinin
  Cc: xen-devel, qemu-devel, sstabellini, anthony.perard, paul.durrant,
	pbonzini

On Tue, 4 Jul 2017, Igor Druzhinin wrote:
> 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 and maps again at the same place using
> a new guest address. If the mapping is dummy this call will
> make it real.
> 
> This function makes use of a new xenforeignmemory_map2() call
> with an 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    | 79 ++++++++++++++++++++++++++++++++++++++-----
>  include/hw/xen/xen_common.h   |  7 ++++
>  include/sysemu/xen-mapcache.h | 11 +++++-
>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> --- a/hw/i386/xen/xen-mapcache.c
> +++ b/hw/i386/xen/xen-mapcache.c
> @@ -151,6 +151,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)
> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry *entry,
>      err = g_malloc0(nb_pfn * sizeof (int));
>  
>      if (entry->vaddr_base != NULL) {
> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> +        if (entry->vaddr_base != vaddr) {
> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> +        }

I would prefer to see checks based on the dummy flag, rather than
entry->vaddr_base != vaddr.


>          if (munmap(entry->vaddr_base, entry->size) != 0) {
>              perror("unmap fails");
>              exit(-1);
> @@ -181,11 +184,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);
>          }

Can we print a warning if (!dummy && vaddr != NULL)?


>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> @@ -194,7 +197,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");
> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry *entry,
>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>      }
>  
> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> +        ram_block_notify_add(vaddr_base, size);
> +    }

Please also check (or check instead) on the dummy flag.


>      entry->vaddr_base = vaddr_base;
>      entry->paddr_index = address_index;
>      entry->size = size;
>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long) *
>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
>  
> -    ram_block_notify_add(entry->vaddr_base, entry->size);
>      bitmap_zero(entry->valid_mapping, nb_pfn);
>      for (i = 0; i < nb_pfn; i++) {
>          if (!err[i]) {
> @@ -282,14 +288,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);
>          }
>      }
>  
> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
>  
>      mapcache_unlock();
>  }
> +
> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
> +                                                 hwaddr new_phys_addr,
> +                                                 hwaddr size)
> +{
> +    MapCacheEntry *entry;
> +    hwaddr address_index;
> +    hwaddr address_offset;
> +    hwaddr cache_size = size;
> +    hwaddr test_bit_size;
> +
> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> +    assert(size);
> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> +    test_bit_size = size + (old_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);
> +    }
> +
> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
> +    while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) {
> +        entry = entry->next;
> +    }
> +    if (!entry) {
> +        DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr);
> +        return NULL;
> +    }
> +
> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> +    }
> +    return entry->vaddr_base + address_offset;
> +}
> +
> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr new_phys_addr, hwaddr size)
> +{
> +    uint8_t *p;
> +
> +    mapcache_lock();
> +    p = xen_replace_cache_entry_unlocked(old_phys_addr, new_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..b38962c 100644
> --- a/include/sysemu/xen-mapcache.h
> +++ b/include/sysemu/xen-mapcache.h
> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> +                                 hwaddr new_phys_addr,
> +                                 hwaddr size);
>  #else
>  
>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
>  {
>  }
>  
> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> +                                 hwaddr new_phys_addr,
> +                                 hwaddr size)
> +{
> +    abort();
> +}
> +
>  #endif
>  
>  #endif /* XEN_MAPCACHE_H */
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-05 22:38     ` Stefano Stabellini
  0 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:38 UTC (permalink / raw)
  To: Igor Druzhinin
  Cc: sstabellini, qemu-devel, paul.durrant, pbonzini, anthony.perard,
	xen-devel

On Tue, 4 Jul 2017, Igor Druzhinin wrote:
> 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 and maps again at the same place using
> a new guest address. If the mapping is dummy this call will
> make it real.
> 
> This function makes use of a new xenforeignmemory_map2() call
> with an 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    | 79 ++++++++++++++++++++++++++++++++++++++-----
>  include/hw/xen/xen_common.h   |  7 ++++
>  include/sysemu/xen-mapcache.h | 11 +++++-
>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> --- a/hw/i386/xen/xen-mapcache.c
> +++ b/hw/i386/xen/xen-mapcache.c
> @@ -151,6 +151,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)
> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry *entry,
>      err = g_malloc0(nb_pfn * sizeof (int));
>  
>      if (entry->vaddr_base != NULL) {
> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> +        if (entry->vaddr_base != vaddr) {
> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> +        }

I would prefer to see checks based on the dummy flag, rather than
entry->vaddr_base != vaddr.


>          if (munmap(entry->vaddr_base, entry->size) != 0) {
>              perror("unmap fails");
>              exit(-1);
> @@ -181,11 +184,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);
>          }

Can we print a warning if (!dummy && vaddr != NULL)?


>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> @@ -194,7 +197,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");
> @@ -203,13 +206,16 @@ static void xen_remap_bucket(MapCacheEntry *entry,
>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
>      }
>  
> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> +        ram_block_notify_add(vaddr_base, size);
> +    }

Please also check (or check instead) on the dummy flag.


>      entry->vaddr_base = vaddr_base;
>      entry->paddr_index = address_index;
>      entry->size = size;
>      entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long) *
>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
>  
> -    ram_block_notify_add(entry->vaddr_base, entry->size);
>      bitmap_zero(entry->valid_mapping, nb_pfn);
>      for (i = 0; i < nb_pfn; i++) {
>          if (!err[i]) {
> @@ -282,14 +288,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);
>          }
>      }
>  
> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
>  
>      mapcache_unlock();
>  }
> +
> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
> +                                                 hwaddr new_phys_addr,
> +                                                 hwaddr size)
> +{
> +    MapCacheEntry *entry;
> +    hwaddr address_index;
> +    hwaddr address_offset;
> +    hwaddr cache_size = size;
> +    hwaddr test_bit_size;
> +
> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> +    assert(size);
> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> +    test_bit_size = size + (old_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);
> +    }
> +
> +    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
> +    while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) {
> +        entry = entry->next;
> +    }
> +    if (!entry) {
> +        DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr);
> +        return NULL;
> +    }
> +
> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> +    }
> +    return entry->vaddr_base + address_offset;
> +}
> +
> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr new_phys_addr, hwaddr size)
> +{
> +    uint8_t *p;
> +
> +    mapcache_lock();
> +    p = xen_replace_cache_entry_unlocked(old_phys_addr, new_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..b38962c 100644
> --- a/include/sysemu/xen-mapcache.h
> +++ b/include/sysemu/xen-mapcache.h
> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> +                                 hwaddr new_phys_addr,
> +                                 hwaddr size);
>  #else
>  
>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> @@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
>  {
>  }
>  
> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> +                                 hwaddr new_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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-05  8:52             ` Paul Durrant
@ 2017-07-05 22:39               ` Stefano Stabellini
  -1 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:39 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Igor Druzhinin, xen-devel, qemu-devel, sstabellini,
	Anthony Perard, pbonzini

On Wed, 5 Jul 2017, Paul Durrant wrote:
> > -----Original Message-----
> > From: Igor Druzhinin
> > Sent: 04 July 2017 17:47
> > To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
> > qemu-devel@nongnu.org
> > Cc: sstabellini@kernel.org; Anthony Perard <anthony.perard@citrix.com>;
> > pbonzini@redhat.com
> > Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> > xen_replace_cache_entry()
> > 
> > On 04/07/17 17:42, Paul Durrant wrote:
> > >> -----Original Message-----
> > >> From: Igor Druzhinin
> > >> Sent: 04 July 2017 17:34
> > >> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-
> > devel@lists.xenproject.org;
> > >> qemu-devel@nongnu.org
> > >> Cc: sstabellini@kernel.org; Anthony Perard
> > <anthony.perard@citrix.com>;
> > >> pbonzini@redhat.com
> > >> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> > >> xen_replace_cache_entry()
> > >>
> > >> On 04/07/17 17:27, Paul Durrant wrote:
> > >>>> -----Original Message-----
> > >>>> From: Igor Druzhinin
> > >>>> Sent: 04 July 2017 16:48
> > >>>> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> > >>>> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> > >>>> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> > >>>> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> > >>>> Subject: [PATCH v2 3/4] xen/mapcache: introduce
> > >>>> xen_replace_cache_entry()
> > >>>>
> > >>>> 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 and maps again at the same place using
> > >>>> a new guest address. If the mapping is dummy this call will
> > >>>> make it real.
> > >>>>
> > >>>> This function makes use of a new xenforeignmemory_map2() call
> > >>>> with an extended interface that was recently introduced in
> > >>>> libxenforeignmemory [1].
> > >>>
> > >>> I don't understand how the compat layer works here. If
> > >> xenforeignmemory_map2() is not available then you can't control the
> > >> placement in virtual address space.
> > >>>
> > >>
> > >> If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
> > >> going to be defined as xenforeignmemory_map(). At the same time
> > >> XEN_COMPAT_PHYSMAP is defined and the entry replace function
> > (which
> > >> relies on xenforeignmemory_map2 functionality) is never going to be
> > called.
> > >>
> > >> If you mean that I should incorporate this into the description I can do it.
> > >
> > > AFAICT XEN_COMPAT_PHYSMAP is not introduced until patch #4 though.
> > >
> > > The problem really comes down to defining xenforeignmemory_map2() in
> > terms of xenforeignmemory_map(). It basically can't be safely done. Could
> > you define xenforeignmemory_map2() as abort() in the compat case
> > instead?
> > >
> > 
> > xen_replace_cache_entry() is not called in patch #3. Which means it's
> > safe to use a fallback version (xenforeignmemory_map) in
> > xen_remap_bucket here.
> 
> I still don't like the fact that the compat definition of xenforeignmemory_map2() loses the extra argument. That's going to catch someone out one day. Is there any way you could re-work it so that xenforeignmemory_map() is uses in the cases where the memory placement does not matter?

We could assert(vaddr == NULL) in the compat implementation of
xenforeignmemory_map2. Would that work?



> > Igor
> > 
> > >   Paul
> > >
> > >>
> > >> Igor
> > >>
> > >>>   Paul
> > >>>
> > >>>>
> > >>>> [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    | 79
> > >>>> ++++++++++++++++++++++++++++++++++++++-----
> > >>>>  include/hw/xen/xen_common.h   |  7 ++++
> > >>>>  include/sysemu/xen-mapcache.h | 11 +++++-
> > >>>>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> > >>>> --- a/hw/i386/xen/xen-mapcache.c
> > >>>> +++ b/hw/i386/xen/xen-mapcache.c
> > >>>> @@ -151,6 +151,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)
> > >>>> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
> > >>>> *entry,
> > >>>>      err = g_malloc0(nb_pfn * sizeof (int));
> > >>>>
> > >>>>      if (entry->vaddr_base != NULL) {
> > >>>> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> > >>>> +        if (entry->vaddr_base != vaddr) {
> > >>>> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> > >>>> +        }
> > >>>>          if (munmap(entry->vaddr_base, entry->size) != 0) {
> > >>>>              perror("unmap fails");
> > >>>>              exit(-1);
> > >>>> @@ -181,11 +184,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);
> > >>>>          }
> > >>>>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> > >>>> @@ -194,7 +197,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");
> > >>>> @@ -203,13 +206,16 @@ static void
> > xen_remap_bucket(MapCacheEntry
> > >>>> *entry,
> > >>>>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
> > >>>>      }
> > >>>>
> > >>>> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> > >>>> +        ram_block_notify_add(vaddr_base, size);
> > >>>> +    }
> > >>>> +
> > >>>>      entry->vaddr_base = vaddr_base;
> > >>>>      entry->paddr_index = address_index;
> > >>>>      entry->size = size;
> > >>>>      entry->valid_mapping = (unsigned long *)
> > g_malloc0(sizeof(unsigned
> > >> long)
> > >>>> *
> > >>>>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> > >>>>
> > >>>> -    ram_block_notify_add(entry->vaddr_base, entry->size);
> > >>>>      bitmap_zero(entry->valid_mapping, nb_pfn);
> > >>>>      for (i = 0; i < nb_pfn; i++) {
> > >>>>          if (!err[i]) {
> > >>>> @@ -282,14 +288,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);
> > >>>>          }
> > >>>>      }
> > >>>>
> > >>>> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
> > >>>>
> > >>>>      mapcache_unlock();
> > >>>>  }
> > >>>> +
> > >>>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
> > >>>> old_phys_addr,
> > >>>> +                                                 hwaddr new_phys_addr,
> > >>>> +                                                 hwaddr size)
> > >>>> +{
> > >>>> +    MapCacheEntry *entry;
> > >>>> +    hwaddr address_index;
> > >>>> +    hwaddr address_offset;
> > >>>> +    hwaddr cache_size = size;
> > >>>> +    hwaddr test_bit_size;
> > >>>> +
> > >>>> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> > >>>> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> > >>>> +
> > >>>> +    assert(size);
> > >>>> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> > >>>> +    test_bit_size = size + (old_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);
> > >>>> +    }
> > >>>> +
> > >>>> +    entry = &mapcache->entry[address_index % mapcache-
> > >nr_buckets];
> > >>>> +    while (entry && !(entry->paddr_index == address_index && entry-
> > >>> size
> > >>>> == cache_size)) {
> > >>>> +        entry = entry->next;
> > >>>> +    }
> > >>>> +    if (!entry) {
> > >>>> +        DPRINTF("Trying to update an entry for %lx that is not in the
> > >>>> mapcache!\n", phys_addr);
> > >>>> +        return NULL;
> > >>>> +    }
> > >>>> +
> > >>>> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> > >>>> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> > >>>> +
> > >>>> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> > >>>> +    }
> > >>>> +
> > >>>> +    return entry->vaddr_base + address_offset;
> > >>>> +}
> > >>>> +
> > >>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
> > >>>> new_phys_addr, hwaddr size)
> > >>>> +{
> > >>>> +    uint8_t *p;
> > >>>> +
> > >>>> +    mapcache_lock();
> > >>>> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
> > >>>> new_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..b38962c 100644
> > >>>> --- a/include/sysemu/xen-mapcache.h
> > >>>> +++ b/include/sysemu/xen-mapcache.h
> > >>>> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> > >>>> +                                 hwaddr new_phys_addr,
> > >>>> +                                 hwaddr size);
> > >>>>  #else
> > >>>>
> > >>>>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> > >>>> @@ -50,6 +52,13 @@ static inline void
> > xen_invalidate_map_cache(void)
> > >>>>  {
> > >>>>  }
> > >>>>
> > >>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> > >>>> +                                 hwaddr new_phys_addr,
> > >>>> +                                 hwaddr size)
> > >>>> +{
> > >>>> +    abort();
> > >>>> +}
> > >>>> +
> > >>>>  #endif
> > >>>>
> > >>>>  #endif /* XEN_MAPCACHE_H */
> > >>>> --
> > >>>> 2.7.4
> > >>>
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-05 22:39               ` Stefano Stabellini
  0 siblings, 0 replies; 38+ messages in thread
From: Stefano Stabellini @ 2017-07-05 22:39 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Igor Druzhinin, sstabellini, qemu-devel, xen-devel,
	Anthony Perard, pbonzini

On Wed, 5 Jul 2017, Paul Durrant wrote:
> > -----Original Message-----
> > From: Igor Druzhinin
> > Sent: 04 July 2017 17:47
> > To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
> > qemu-devel@nongnu.org
> > Cc: sstabellini@kernel.org; Anthony Perard <anthony.perard@citrix.com>;
> > pbonzini@redhat.com
> > Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> > xen_replace_cache_entry()
> > 
> > On 04/07/17 17:42, Paul Durrant wrote:
> > >> -----Original Message-----
> > >> From: Igor Druzhinin
> > >> Sent: 04 July 2017 17:34
> > >> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-
> > devel@lists.xenproject.org;
> > >> qemu-devel@nongnu.org
> > >> Cc: sstabellini@kernel.org; Anthony Perard
> > <anthony.perard@citrix.com>;
> > >> pbonzini@redhat.com
> > >> Subject: Re: [PATCH v2 3/4] xen/mapcache: introduce
> > >> xen_replace_cache_entry()
> > >>
> > >> On 04/07/17 17:27, Paul Durrant wrote:
> > >>>> -----Original Message-----
> > >>>> From: Igor Druzhinin
> > >>>> Sent: 04 July 2017 16:48
> > >>>> To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org
> > >>>> Cc: Igor Druzhinin <igor.druzhinin@citrix.com>; sstabellini@kernel.org;
> > >>>> Anthony Perard <anthony.perard@citrix.com>; Paul Durrant
> > >>>> <Paul.Durrant@citrix.com>; pbonzini@redhat.com
> > >>>> Subject: [PATCH v2 3/4] xen/mapcache: introduce
> > >>>> xen_replace_cache_entry()
> > >>>>
> > >>>> 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 and maps again at the same place using
> > >>>> a new guest address. If the mapping is dummy this call will
> > >>>> make it real.
> > >>>>
> > >>>> This function makes use of a new xenforeignmemory_map2() call
> > >>>> with an extended interface that was recently introduced in
> > >>>> libxenforeignmemory [1].
> > >>>
> > >>> I don't understand how the compat layer works here. If
> > >> xenforeignmemory_map2() is not available then you can't control the
> > >> placement in virtual address space.
> > >>>
> > >>
> > >> If it's not 4.10 or newer xenforeignmemory_map2() doesn't exist and is
> > >> going to be defined as xenforeignmemory_map(). At the same time
> > >> XEN_COMPAT_PHYSMAP is defined and the entry replace function
> > (which
> > >> relies on xenforeignmemory_map2 functionality) is never going to be
> > called.
> > >>
> > >> If you mean that I should incorporate this into the description I can do it.
> > >
> > > AFAICT XEN_COMPAT_PHYSMAP is not introduced until patch #4 though.
> > >
> > > The problem really comes down to defining xenforeignmemory_map2() in
> > terms of xenforeignmemory_map(). It basically can't be safely done. Could
> > you define xenforeignmemory_map2() as abort() in the compat case
> > instead?
> > >
> > 
> > xen_replace_cache_entry() is not called in patch #3. Which means it's
> > safe to use a fallback version (xenforeignmemory_map) in
> > xen_remap_bucket here.
> 
> I still don't like the fact that the compat definition of xenforeignmemory_map2() loses the extra argument. That's going to catch someone out one day. Is there any way you could re-work it so that xenforeignmemory_map() is uses in the cases where the memory placement does not matter?

We could assert(vaddr == NULL) in the compat implementation of
xenforeignmemory_map2. Would that work?



> > Igor
> > 
> > >   Paul
> > >
> > >>
> > >> Igor
> > >>
> > >>>   Paul
> > >>>
> > >>>>
> > >>>> [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    | 79
> > >>>> ++++++++++++++++++++++++++++++++++++++-----
> > >>>>  include/hw/xen/xen_common.h   |  7 ++++
> > >>>>  include/sysemu/xen-mapcache.h | 11 +++++-
> > >>>>  4 files changed, 106 insertions(+), 9 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 cd4e746..a988be7 100644
> > >>>> --- a/hw/i386/xen/xen-mapcache.c
> > >>>> +++ b/hw/i386/xen/xen-mapcache.c
> > >>>> @@ -151,6 +151,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)
> > >>>> @@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry
> > >>>> *entry,
> > >>>>      err = g_malloc0(nb_pfn * sizeof (int));
> > >>>>
> > >>>>      if (entry->vaddr_base != NULL) {
> > >>>> -        ram_block_notify_remove(entry->vaddr_base, entry->size);
> > >>>> +        if (entry->vaddr_base != vaddr) {
> > >>>> +            ram_block_notify_remove(entry->vaddr_base, entry->size);
> > >>>> +        }
> > >>>>          if (munmap(entry->vaddr_base, entry->size) != 0) {
> > >>>>              perror("unmap fails");
> > >>>>              exit(-1);
> > >>>> @@ -181,11 +184,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);
> > >>>>          }
> > >>>>          entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
> > >>>> @@ -194,7 +197,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");
> > >>>> @@ -203,13 +206,16 @@ static void
> > xen_remap_bucket(MapCacheEntry
> > >>>> *entry,
> > >>>>          entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
> > >>>>      }
> > >>>>
> > >>>> +    if (entry->vaddr_base == NULL || entry->vaddr_base != vaddr) {
> > >>>> +        ram_block_notify_add(vaddr_base, size);
> > >>>> +    }
> > >>>> +
> > >>>>      entry->vaddr_base = vaddr_base;
> > >>>>      entry->paddr_index = address_index;
> > >>>>      entry->size = size;
> > >>>>      entry->valid_mapping = (unsigned long *)
> > g_malloc0(sizeof(unsigned
> > >> long)
> > >>>> *
> > >>>>              BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> > >>>>
> > >>>> -    ram_block_notify_add(entry->vaddr_base, entry->size);
> > >>>>      bitmap_zero(entry->valid_mapping, nb_pfn);
> > >>>>      for (i = 0; i < nb_pfn; i++) {
> > >>>>          if (!err[i]) {
> > >>>> @@ -282,14 +288,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);
> > >>>>          }
> > >>>>      }
> > >>>>
> > >>>> @@ -486,3 +492,60 @@ void xen_invalidate_map_cache(void)
> > >>>>
> > >>>>      mapcache_unlock();
> > >>>>  }
> > >>>> +
> > >>>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr
> > >>>> old_phys_addr,
> > >>>> +                                                 hwaddr new_phys_addr,
> > >>>> +                                                 hwaddr size)
> > >>>> +{
> > >>>> +    MapCacheEntry *entry;
> > >>>> +    hwaddr address_index;
> > >>>> +    hwaddr address_offset;
> > >>>> +    hwaddr cache_size = size;
> > >>>> +    hwaddr test_bit_size;
> > >>>> +
> > >>>> +    address_index  = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> > >>>> +    address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> > >>>> +
> > >>>> +    assert(size);
> > >>>> +    /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> > >>>> +    test_bit_size = size + (old_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);
> > >>>> +    }
> > >>>> +
> > >>>> +    entry = &mapcache->entry[address_index % mapcache-
> > >nr_buckets];
> > >>>> +    while (entry && !(entry->paddr_index == address_index && entry-
> > >>> size
> > >>>> == cache_size)) {
> > >>>> +        entry = entry->next;
> > >>>> +    }
> > >>>> +    if (!entry) {
> > >>>> +        DPRINTF("Trying to update an entry for %lx that is not in the
> > >>>> mapcache!\n", phys_addr);
> > >>>> +        return NULL;
> > >>>> +    }
> > >>>> +
> > >>>> +    address_index  = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> > >>>> +    address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> > >>>> +
> > >>>> +    xen_remap_bucket(entry, entry->vaddr_base, 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;
> > >>>> +    }
> > >>>> +
> > >>>> +    return entry->vaddr_base + address_offset;
> > >>>> +}
> > >>>> +
> > >>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr
> > >>>> new_phys_addr, hwaddr size)
> > >>>> +{
> > >>>> +    uint8_t *p;
> > >>>> +
> > >>>> +    mapcache_lock();
> > >>>> +    p = xen_replace_cache_entry_unlocked(old_phys_addr,
> > >>>> new_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..b38962c 100644
> > >>>> --- a/include/sysemu/xen-mapcache.h
> > >>>> +++ b/include/sysemu/xen-mapcache.h
> > >>>> @@ -21,7 +21,9 @@ 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_replace_cache_entry(hwaddr old_phys_addr,
> > >>>> +                                 hwaddr new_phys_addr,
> > >>>> +                                 hwaddr size);
> > >>>>  #else
> > >>>>
> > >>>>  static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
> > >>>> @@ -50,6 +52,13 @@ static inline void
> > xen_invalidate_map_cache(void)
> > >>>>  {
> > >>>>  }
> > >>>>
> > >>>> +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> > >>>> +                                 hwaddr new_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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
  2017-07-05 22:39               ` Stefano Stabellini
@ 2017-07-06  9:50                 ` Paul Durrant
  -1 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-06  9:50 UTC (permalink / raw)
  To: 'Stefano Stabellini'
  Cc: Igor Druzhinin, xen-devel, qemu-devel, Anthony Perard, pbonzini

> -----Original Message-----
> > > >
> > > > The problem really comes down to defining
> xenforeignmemory_map2() in
> > > terms of xenforeignmemory_map(). It basically can't be safely done.
> Could
> > > you define xenforeignmemory_map2() as abort() in the compat case
> > > instead?
> > > >
> > >
> > > xen_replace_cache_entry() is not called in patch #3. Which means it's
> > > safe to use a fallback version (xenforeignmemory_map) in
> > > xen_remap_bucket here.
> >
> > I still don't like the fact that the compat definition of
> xenforeignmemory_map2() loses the extra argument. That's going to catch
> someone out one day. Is there any way you could re-work it so that
> xenforeignmemory_map() is uses in the cases where the memory
> placement does not matter?
> 
> We could assert(vaddr == NULL) in the compat implementation of
> xenforeignmemory_map2. Would that work?
> 

Yes, if the patch was changed from being a straight #define as it is now to an inline that had such an assertion then that would be ok.

  Cheers,

    Paul

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry()
@ 2017-07-06  9:50                 ` Paul Durrant
  0 siblings, 0 replies; 38+ messages in thread
From: Paul Durrant @ 2017-07-06  9:50 UTC (permalink / raw)
  To: 'Stefano Stabellini'
  Cc: Anthony Perard, Igor Druzhinin, pbonzini, qemu-devel, xen-devel

> -----Original Message-----
> > > >
> > > > The problem really comes down to defining
> xenforeignmemory_map2() in
> > > terms of xenforeignmemory_map(). It basically can't be safely done.
> Could
> > > you define xenforeignmemory_map2() as abort() in the compat case
> > > instead?
> > > >
> > >
> > > xen_replace_cache_entry() is not called in patch #3. Which means it's
> > > safe to use a fallback version (xenforeignmemory_map) in
> > > xen_remap_bucket here.
> >
> > I still don't like the fact that the compat definition of
> xenforeignmemory_map2() loses the extra argument. That's going to catch
> someone out one day. Is there any way you could re-work it so that
> xenforeignmemory_map() is uses in the cases where the memory
> placement does not matter?
> 
> We could assert(vaddr == NULL) in the compat implementation of
> xenforeignmemory_map2. Would that work?
> 

Yes, if the patch was changed from being a straight #define as it is now to an inline that had such an assertion then that would be ok.

  Cheers,

    Paul

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] xen: don't save/restore the physmap on VM save/restore
  2017-07-04 15:47 ` Igor Druzhinin
@ 2017-07-06 13:57   ` no-reply
  -1 siblings, 0 replies; 38+ messages in thread
From: no-reply @ 2017-07-06 13:57 UTC (permalink / raw)
  To: igor.druzhinin
  Cc: famz, xen-devel, qemu-devel, anthony.perard, sstabellini,
	paul.durrant, pbonzini

Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 1499183267-28623-1-git-send-email-igor.druzhinin@citrix.com
Type: series
Subject: [Qemu-devel] [PATCH v2 0/4] xen: don't save/restore the physmap on VM save/restore

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
c5f49bf xen: don't use xenstore to save/restore physmap anymore
da3fc1b xen/mapcache: introduce xen_replace_cache_entry()
e9069c8 xen/mapcache: add an ability to create dummy mappings
dfbd8c6 xen: move physmap saving into a separate function

=== OUTPUT BEGIN ===
Checking PATCH 1/4: xen: move physmap saving into a separate function...
Checking PATCH 2/4: xen/mapcache: add an ability to create dummy mappings...
ERROR: spaces required around that '|' (ctx:VxV)
#52: FILE: hw/i386/xen/xen-mapcache.c:185:
+                                           PROT_READ|PROT_WRITE,
                                                     ^

ERROR: spaces required around that '|' (ctx:VxV)
#64: FILE: hw/i386/xen/xen-mapcache.c:197:
+        vaddr_base = mmap(NULL, size, PROT_READ|PROT_WRITE,
                                                ^

ERROR: spaces required around that '|' (ctx:VxV)
#65: FILE: hw/i386/xen/xen-mapcache.c:198:
+                          MAP_ANON|MAP_SHARED, -1, 0);
                                   ^

total: 3 errors, 0 warnings, 82 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 3/4: xen/mapcache: introduce xen_replace_cache_entry()...
ERROR: spaces required around that '|' (ctx:VxV)
#80: FILE: hw/i386/xen/xen-mapcache.c:188:
+                                           PROT_READ|PROT_WRITE, 0,
                                                     ^

ERROR: spaces required around that '|' (ctx:VxV)
#93: FILE: hw/i386/xen/xen-mapcache.c:200:
+        vaddr_base = mmap(vaddr, size, PROT_READ|PROT_WRITE,
                                                 ^

WARNING: line over 80 characters
#162: FILE: hw/i386/xen/xen-mapcache.c:521:
+    while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) {

ERROR: line over 90 characters
#166: FILE: hw/i386/xen/xen-mapcache.c:525:
+        DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr);

WARNING: line over 80 characters
#173: FILE: hw/i386/xen/xen-mapcache.c:532:
+    xen_remap_bucket(entry, entry->vaddr_base, cache_size, address_index, false);

ERROR: space required before the open parenthesis '('
#174: FILE: hw/i386/xen/xen-mapcache.c:533:
+    if(!test_bits(address_offset >> XC_PAGE_SHIFT,

WARNING: line over 80 characters
#177: FILE: hw/i386/xen/xen-mapcache.c:536:
+        DPRINTF("Unable to update an entry for %lx in the mapcache!\n", phys_addr);

WARNING: line over 80 characters
#184: FILE: hw/i386/xen/xen-mapcache.c:543:
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr new_phys_addr, hwaddr size)

total: 4 errors, 4 warnings, 192 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 4/4: xen: don't use xenstore to save/restore physmap anymore...
ERROR: space prohibited between function name and open parenthesis '('
#47: FILE: hw/i386/xen/xen-hvm.c:380:
+    physmap = g_malloc(sizeof (XenPhysmap));

total: 1 errors, 0 warnings, 98 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] xen: don't save/restore the physmap on VM save/restore
@ 2017-07-06 13:57   ` no-reply
  0 siblings, 0 replies; 38+ messages in thread
From: no-reply @ 2017-07-06 13:57 UTC (permalink / raw)
  Cc: igor.druzhinin, sstabellini, famz, qemu-devel, paul.durrant,
	pbonzini, anthony.perard, xen-devel

Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 1499183267-28623-1-git-send-email-igor.druzhinin@citrix.com
Type: series
Subject: [Qemu-devel] [PATCH v2 0/4] xen: don't save/restore the physmap on VM save/restore

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
c5f49bf xen: don't use xenstore to save/restore physmap anymore
da3fc1b xen/mapcache: introduce xen_replace_cache_entry()
e9069c8 xen/mapcache: add an ability to create dummy mappings
dfbd8c6 xen: move physmap saving into a separate function

=== OUTPUT BEGIN ===
Checking PATCH 1/4: xen: move physmap saving into a separate function...
Checking PATCH 2/4: xen/mapcache: add an ability to create dummy mappings...
ERROR: spaces required around that '|' (ctx:VxV)
#52: FILE: hw/i386/xen/xen-mapcache.c:185:
+                                           PROT_READ|PROT_WRITE,
                                                     ^

ERROR: spaces required around that '|' (ctx:VxV)
#64: FILE: hw/i386/xen/xen-mapcache.c:197:
+        vaddr_base = mmap(NULL, size, PROT_READ|PROT_WRITE,
                                                ^

ERROR: spaces required around that '|' (ctx:VxV)
#65: FILE: hw/i386/xen/xen-mapcache.c:198:
+                          MAP_ANON|MAP_SHARED, -1, 0);
                                   ^

total: 3 errors, 0 warnings, 82 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 3/4: xen/mapcache: introduce xen_replace_cache_entry()...
ERROR: spaces required around that '|' (ctx:VxV)
#80: FILE: hw/i386/xen/xen-mapcache.c:188:
+                                           PROT_READ|PROT_WRITE, 0,
                                                     ^

ERROR: spaces required around that '|' (ctx:VxV)
#93: FILE: hw/i386/xen/xen-mapcache.c:200:
+        vaddr_base = mmap(vaddr, size, PROT_READ|PROT_WRITE,
                                                 ^

WARNING: line over 80 characters
#162: FILE: hw/i386/xen/xen-mapcache.c:521:
+    while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) {

ERROR: line over 90 characters
#166: FILE: hw/i386/xen/xen-mapcache.c:525:
+        DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr);

WARNING: line over 80 characters
#173: FILE: hw/i386/xen/xen-mapcache.c:532:
+    xen_remap_bucket(entry, entry->vaddr_base, cache_size, address_index, false);

ERROR: space required before the open parenthesis '('
#174: FILE: hw/i386/xen/xen-mapcache.c:533:
+    if(!test_bits(address_offset >> XC_PAGE_SHIFT,

WARNING: line over 80 characters
#177: FILE: hw/i386/xen/xen-mapcache.c:536:
+        DPRINTF("Unable to update an entry for %lx in the mapcache!\n", phys_addr);

WARNING: line over 80 characters
#184: FILE: hw/i386/xen/xen-mapcache.c:543:
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, hwaddr new_phys_addr, hwaddr size)

total: 4 errors, 4 warnings, 192 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 4/4: xen: don't use xenstore to save/restore physmap anymore...
ERROR: space prohibited between function name and open parenthesis '('
#47: FILE: hw/i386/xen/xen-hvm.c:380:
+    physmap = g_malloc(sizeof (XenPhysmap));

total: 1 errors, 0 warnings, 98 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2017-07-06 13:57 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-04 15:47 [Qemu-devel] [PATCH v2 0/4] xen: don't save/restore the physmap on VM save/restore Igor Druzhinin
2017-07-04 15:47 ` Igor Druzhinin
2017-07-04 15:47 ` [Qemu-devel] [PATCH v2 1/4] xen: move physmap saving into a separate function Igor Druzhinin
2017-07-04 15:47   ` Igor Druzhinin
2017-07-04 16:05   ` [Qemu-devel] " Paul Durrant
2017-07-04 16:05     ` Paul Durrant
2017-07-05 22:16   ` [Qemu-devel] " Stefano Stabellini
2017-07-05 22:16     ` Stefano Stabellini
2017-07-04 15:47 ` [Qemu-devel] [PATCH v2 2/4] xen/mapcache: add an ability to create dummy mappings Igor Druzhinin
2017-07-04 15:47   ` Igor Druzhinin
2017-07-04 16:11   ` [Qemu-devel] " Paul Durrant
2017-07-04 16:11     ` Paul Durrant
2017-07-05 22:38   ` [Qemu-devel] " Stefano Stabellini
2017-07-05 22:38     ` Stefano Stabellini
2017-07-04 15:47 ` [Qemu-devel] [PATCH v2 3/4] xen/mapcache: introduce xen_replace_cache_entry() Igor Druzhinin
2017-07-04 15:47   ` Igor Druzhinin
2017-07-04 16:27   ` [Qemu-devel] " Paul Durrant
2017-07-04 16:27     ` Paul Durrant
2017-07-04 16:34     ` [Qemu-devel] " Igor Druzhinin
2017-07-04 16:34       ` Igor Druzhinin
2017-07-04 16:42       ` [Qemu-devel] " Paul Durrant
2017-07-04 16:42         ` Paul Durrant
2017-07-04 16:46         ` [Qemu-devel] " Igor Druzhinin
2017-07-04 16:46           ` Igor Druzhinin
2017-07-05  8:52           ` [Qemu-devel] " Paul Durrant
2017-07-05  8:52             ` Paul Durrant
2017-07-05 22:39             ` [Qemu-devel] " Stefano Stabellini
2017-07-05 22:39               ` Stefano Stabellini
2017-07-06  9:50               ` [Qemu-devel] " Paul Durrant
2017-07-06  9:50                 ` Paul Durrant
2017-07-05 22:38   ` [Qemu-devel] " Stefano Stabellini
2017-07-05 22:38     ` Stefano Stabellini
2017-07-04 15:47 ` [Qemu-devel] [PATCH v2 4/4] xen: don't use xenstore to save/restore physmap anymore Igor Druzhinin
2017-07-04 15:47   ` Igor Druzhinin
2017-07-05 22:38   ` [Qemu-devel] " Stefano Stabellini
2017-07-05 22:38     ` Stefano Stabellini
2017-07-06 13:57 ` [Qemu-devel] [PATCH v2 0/4] xen: don't save/restore the physmap on VM save/restore no-reply
2017-07-06 13:57   ` no-reply

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.