[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] hvm: Do not save/restore shared_info gpfn location.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1174322904 0
# Node ID 36e6f85cd57232ce5c881cae75e2c178cb26bbe4
# Parent  ed1e4cc4a5b7251a02877c7ba1b29e87c47ac145
hvm: Do not save/restore shared_info gpfn location.

Instead of kludging a max_gpfn estimate in shared_info, add a new
XENMEM command to discover the actual maximum gpfn value as known by
the shadow code.

This needs to be more robust when we support HVM ballooning in future
anyway. One interesting point is that max_gpfn may be close to 4GB
even for small-memory HVM guests since for example SVGA LFB is mapped
into the I/O hole. We may need to special case the I/O hole somehow,
or provide some finer-grained way to find out which parts of the GPFN
space are actually used (e.g., get Xen to fill in a bitmap with 1 bit
per 1024 pages, or similar).

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/libxc/xc_core_x86.c       |   24 +++++++++++-------------
 tools/libxc/xc_hvm_build.c      |    1 -
 tools/libxc/xc_hvm_restore.c    |   31 -------------------------------
 tools/libxc/xc_hvm_save.c       |   30 +-----------------------------
 tools/libxc/xc_private.c        |   14 ++++++++++++++
 xen/arch/x86/mm.c               |    6 ++++++
 xen/arch/x86/mm/shadow/common.c |    6 +++---
 xen/common/compat/memory.c      |    2 ++
 xen/common/memory.c             |   15 ++++++++++++++-
 xen/include/asm-ia64/mm.h       |    2 ++
 xen/include/asm-powerpc/mm.h    |    2 ++
 xen/include/asm-x86/mm.h        |    1 +
 xen/include/public/memory.h     |    5 +++++
 13 files changed, 61 insertions(+), 78 deletions(-)

diff -r ed1e4cc4a5b7 -r 36e6f85cd572 tools/libxc/xc_core_x86.c
--- a/tools/libxc/xc_core_x86.c Mon Mar 19 16:28:24 2007 +0000
+++ b/tools/libxc/xc_core_x86.c Mon Mar 19 16:48:24 2007 +0000
@@ -21,12 +21,15 @@
 #include "xg_private.h"
 #include "xc_core.h"
 
+static int max_gpfn(int xc_handle, domid_t domid)
+{
+    return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid);
+}
+
 int
 xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
 {
-    if ( info->hvm )
-        return 1;
-    return 0;
+    return info->hvm;
 }
 
 int
@@ -35,14 +38,14 @@ xc_core_arch_memory_map_get(int xc_handl
                             xc_core_memory_map_t **mapp,
                             unsigned int *nr_entries)
 {
-    unsigned long max_pfn = live_shinfo->arch.max_pfn;
-    xc_core_memory_map_t *map = NULL;
+    unsigned long max_pfn = max_gpfn(xc_handle, info->domid);
+    xc_core_memory_map_t *map;
 
     map = malloc(sizeof(*map));
-    if ( !map )
+    if ( map == NULL )
     {
         PERROR("Could not allocate memory");
-        goto out;
+        return -1;
     }
 
     map->addr = 0;
@@ -51,11 +54,6 @@ xc_core_arch_memory_map_get(int xc_handl
     *mapp = map;
     *nr_entries = 1;
     return 0;
-
-out:
-    if ( map )
-        free(map);
-    return -1;
 }
 
 int
@@ -67,7 +65,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
     xen_pfn_t *live_p2m_frame_list_list = NULL;
     xen_pfn_t *live_p2m_frame_list = NULL;
     uint32_t dom = info->domid;
-    unsigned long max_pfn = live_shinfo->arch.max_pfn;
+    unsigned long max_pfn = max_gpfn(xc_handle, info->domid);
     int ret = -1;
     int err;
 
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Mon Mar 19 16:28:24 2007 +0000
+++ b/tools/libxc/xc_hvm_build.c        Mon Mar 19 16:48:24 2007 +0000
@@ -286,7 +286,6 @@ static int setup_guest(int xc_handle,
     /* NB. evtchn_upcall_mask is unused: leave as zero. */
     memset(&shared_info->evtchn_mask[0], 0xff,
            sizeof(shared_info->evtchn_mask));
-    shared_info->arch.max_pfn = page_array[nr_pages - 1];
     munmap(shared_info, PAGE_SIZE);
 
     if ( v_end > HVM_BELOW_4G_RAM_END )
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 tools/libxc/xc_hvm_restore.c
--- a/tools/libxc/xc_hvm_restore.c      Mon Mar 19 16:28:24 2007 +0000
+++ b/tools/libxc/xc_hvm_restore.c      Mon Mar 19 16:48:24 2007 +0000
@@ -70,9 +70,6 @@ int xc_hvm_restore(int xc_handle, int io
 {
     DECLARE_DOMCTL;
 
-    /* The new domain's shared-info frame number. */
-    unsigned long shared_info_frame;
-
     /* A copy of the CPU context of the guest. */
     vcpu_guest_context_t ctxt;
 
@@ -86,8 +83,6 @@ int xc_hvm_restore(int xc_handle, int io
     uint8_t *hvm_buf = NULL;
     unsigned long long v_end, memsize;
     unsigned long shared_page_nr;
-    shared_info_t *shared_info = NULL;
-    xen_pfn_t arch_max_pfn;
 
     unsigned long pfn;
     unsigned int prev_pc, this_pc;
@@ -95,8 +90,6 @@ int xc_hvm_restore(int xc_handle, int io
 
     /* Types of the pfns in the current region */
     unsigned long region_pfn_type[MAX_BATCH_SIZE];
-
-    struct xen_add_to_physmap xatp;
 
     /* Number of pages of memory the guest has.  *Not* the same as max_pfn. */
     unsigned long nr_pages;
@@ -146,7 +139,6 @@ int xc_hvm_restore(int xc_handle, int io
         pfns[i] = i;
     for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < pfn_array_size; i++ )
         pfns[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
-    arch_max_pfn = pfns[max_pfn];/* used later */
 
     /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
     rc = xc_domain_memory_populate_physmap(
@@ -350,29 +342,6 @@ int xc_hvm_restore(int xc_handle, int io
         goto out;
     }
 
-    /* Shared-info pfn */
-    if (!read_exact(io_fd, &(shared_info_frame), sizeof(uint32_t)) ) {
-        ERROR("reading the shared-info pfn failed!\n");
-        goto out;
-    }
-    /* Map the shared-info frame where it was before */
-    xatp.domid = dom;
-    xatp.space = XENMAPSPACE_shared_info;
-    xatp.idx   = 0;
-    xatp.gpfn  = shared_info_frame;
-    if ( (rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp)) != 0 ) {
-        ERROR("setting the shared-info pfn failed!\n");
-        goto out;
-    }
-    if ( (xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp) != 0) ||
-         ((shared_info = xc_map_foreign_range(
-             xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
-             shared_info_frame)) == NULL) )
-        goto out;
-    /* shared_info.arch.max_pfn is used by dump-core */
-    shared_info->arch.max_pfn = arch_max_pfn;
-    munmap(shared_info, PAGE_SIZE);
-
     rc = 0;
     goto out;
 
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 tools/libxc/xc_hvm_save.c
--- a/tools/libxc/xc_hvm_save.c Mon Mar 19 16:28:24 2007 +0000
+++ b/tools/libxc/xc_hvm_save.c Mon Mar 19 16:48:24 2007 +0000
@@ -302,9 +302,6 @@ int xc_hvm_save(int xc_handle, int io_fd
     /* The size of an array big enough to contain all guest pfns */
     unsigned long pfn_array_size;
 
-    /* The new domain's shared-info frame number. */
-    unsigned long shared_info_frame;
-
     /* Other magic frames: ioreqs and xenstore comms */
     unsigned long ioreq_pfn, bufioreq_pfn, store_pfn;
 
@@ -317,9 +314,6 @@ int xc_hvm_save(int xc_handle, int io_fd
     /* A copy of hvm domain context buffer*/
     uint32_t hvm_buf_size;
     uint8_t *hvm_buf = NULL;
-
-    /* Live mapping of shared info structure */
-    shared_info_t *live_shinfo = NULL;
 
     /* base of the region in which domain memory is mapped */
     unsigned char *region_base = NULL;
@@ -372,19 +366,11 @@ int xc_hvm_save(int xc_handle, int io_fd
         ERROR("HVM:Could not get vcpu context");
         goto out;
     }
-    shared_info_frame = info.shared_info_frame;
 
     /* cheesy sanity check */
     if ((info.max_memkb >> (PAGE_SHIFT - 10)) > max_mfn) {
         ERROR("Invalid HVM state record -- pfn count out of range: %lu",
             (info.max_memkb >> (PAGE_SHIFT - 10)));
-        goto out;
-    }
-
-    /* Map the shared info frame */
-    if(!(live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
-                                            PROT_READ, shared_info_frame))) {
-        ERROR("HVM:Couldn't map live_shinfo");
         goto out;
     }
 
@@ -525,13 +511,6 @@ int xc_hvm_save(int xc_handle, int io_fd
 
         DPRINTF("Saving HVM domain memory pages: iter %d   0%%", iter);
 
-        if (last_iter && (max_pfn != live_shinfo->arch.max_pfn)) {
-            DPRINTF("calculated max_pfn as %#lx, shinfo says %#lx\n",
-                    max_pfn, live_shinfo->arch.max_pfn);
-            ERROR("Max pfn doesn't match shared info");
-            goto out;
-        }
-
         while( N < pfn_array_size ){
 
             unsigned int this_pc = (N * 100) / pfn_array_size;
@@ -679,8 +658,7 @@ int xc_hvm_save(int xc_handle, int io_fd
                     goto out;
                 }
 
-                DPRINTF("SUSPEND shinfo %08lx eip %08lx edx %08lx\n",
-                        info.shared_info_frame,
+                DPRINTF("SUSPEND eip %08lx edx %08lx\n",
                         (unsigned long)ctxt.user_regs.eip,
                         (unsigned long)ctxt.user_regs.edx);
             }
@@ -768,12 +746,6 @@ int xc_hvm_save(int xc_handle, int io_fd
         ERROR("write HVM info failed!\n");
     }
 
-    /* Shared-info pfn */
-    if (!write_exact(io_fd, &(shared_info_frame), sizeof(uint32_t)) ) {
-        ERROR("write shared-info pfn failed!\n");
-        goto out;
-    }
- 
     /* Success! */
     rc = 0;
 
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Mon Mar 19 16:28:24 2007 +0000
+++ b/tools/libxc/xc_private.c  Mon Mar 19 16:48:24 2007 +0000
@@ -263,6 +263,15 @@ int xc_memory_op(int xc_handle,
             goto out1;
         }
         break;
+    case XENMEM_current_reservation:
+    case XENMEM_maximum_reservation:
+    case XENMEM_maximum_gpfn:
+        if ( lock_pages(arg, sizeof(domid_t)) )
+        {
+            PERROR("Could not lock");
+            goto out1;
+        }
+        break;
     }
 
     ret = do_xen_hypercall(xc_handle, &hypercall);
@@ -286,6 +295,11 @@ int xc_memory_op(int xc_handle,
         break;
     case XENMEM_add_to_physmap:
         unlock_pages(arg, sizeof(struct xen_add_to_physmap));
+        break;
+    case XENMEM_current_reservation:
+    case XENMEM_maximum_reservation:
+    case XENMEM_maximum_gpfn:
+        unlock_pages(arg, sizeof(domid_t));
         break;
     }
 
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Mar 19 16:28:24 2007 +0000
+++ b/xen/arch/x86/mm.c Mon Mar 19 16:48:24 2007 +0000
@@ -108,6 +108,7 @@
 #include <asm/x86_emulate.h>
 #include <asm/e820.h>
 #include <asm/hypercall.h>
+#include <asm/shared.h>
 #include <public/memory.h>
 
 #define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
@@ -244,6 +245,11 @@ int memory_is_conventional_ram(paddr_t p
     }
 
     return 0;
+}
+
+unsigned long domain_get_maximum_gpfn(struct domain *d)
+{
+    return is_hvm_domain(d) ? d->arch.p2m.max_mapped_pfn : arch_get_max_pfn(d);
 }
 
 void share_xen_page_with_guest(
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Mon Mar 19 16:28:24 2007 +0000
+++ b/xen/arch/x86/mm/shadow/common.c   Mon Mar 19 16:48:24 2007 +0000
@@ -36,7 +36,6 @@
 #include <asm/current.h>
 #include <asm/flushtlb.h>
 #include <asm/shadow.h>
-#include <asm/shared.h>
 #include "private.h"
 
 
@@ -2672,7 +2671,7 @@ sh_alloc_log_dirty_bitmap(struct domain 
 {
     ASSERT(d->arch.paging.shadow.dirty_bitmap == NULL);
     d->arch.paging.shadow.dirty_bitmap_size =
-        (arch_get_max_pfn(d) + (BITS_PER_LONG - 1)) &
+        (domain_get_maximum_gpfn(d) + (BITS_PER_LONG - 1)) &
         ~(BITS_PER_LONG - 1);
     d->arch.paging.shadow.dirty_bitmap =
         xmalloc_array(unsigned long,
@@ -2682,7 +2681,8 @@ sh_alloc_log_dirty_bitmap(struct domain 
         d->arch.paging.shadow.dirty_bitmap_size = 0;
         return -ENOMEM;
     }
-    memset(d->arch.paging.shadow.dirty_bitmap, 0, 
d->arch.paging.shadow.dirty_bitmap_size/8);
+    memset(d->arch.paging.shadow.dirty_bitmap, 0,
+           d->arch.paging.shadow.dirty_bitmap_size/8);
 
     return 0;
 }
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 xen/common/compat/memory.c
--- a/xen/common/compat/memory.c        Mon Mar 19 16:28:24 2007 +0000
+++ b/xen/common/compat/memory.c        Mon Mar 19 16:48:24 2007 +0000
@@ -170,6 +170,7 @@ int compat_memory_op(unsigned int cmd, X
 
         case XENMEM_current_reservation:
         case XENMEM_maximum_reservation:
+        case XENMEM_maximum_gpfn:
         {
 #define xen_domid_t domid_t
 #define compat_domid_t domid_compat_t
@@ -325,6 +326,7 @@ int compat_memory_op(unsigned int cmd, X
         case XENMEM_maximum_ram_page:
         case XENMEM_current_reservation:
         case XENMEM_maximum_reservation:
+        case XENMEM_maximum_gpfn:
             break;
 
         case XENMEM_translate_gpfn_list:
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 xen/common/memory.c
--- a/xen/common/memory.c       Mon Mar 19 16:28:24 2007 +0000
+++ b/xen/common/memory.c       Mon Mar 19 16:48:24 2007 +0000
@@ -584,6 +584,7 @@ long do_memory_op(unsigned long cmd, XEN
 
     case XENMEM_current_reservation:
     case XENMEM_maximum_reservation:
+    case XENMEM_maximum_gpfn:
         if ( copy_from_guest(&domid, arg, 1) )
             return -EFAULT;
 
@@ -594,7 +595,19 @@ long do_memory_op(unsigned long cmd, XEN
         else if ( (d = rcu_lock_domain_by_id(domid)) == NULL )
             return -ESRCH;
 
-        rc = (op == XENMEM_current_reservation) ? d->tot_pages : d->max_pages;
+        switch ( op )
+        {
+        case XENMEM_current_reservation:
+            rc = d->tot_pages;
+            break;
+        case XENMEM_maximum_reservation:
+            rc = d->max_pages;
+            break;
+        default:
+            ASSERT(op == XENMEM_maximum_gpfn);
+            rc = domain_get_maximum_gpfn(d);
+            break;
+        }
 
         if ( unlikely(domid != DOMID_SELF) )
             rcu_unlock_domain(d);
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Mon Mar 19 16:28:24 2007 +0000
+++ b/xen/include/asm-ia64/mm.h Mon Mar 19 16:48:24 2007 +0000
@@ -511,4 +511,6 @@ int steal_page(
 
 #define domain_clamp_alloc_bitsize(d, b) (b)
 
+#define domain_get_maximum_gpfn(d) (-ENOSYS)
+
 #endif /* __ASM_IA64_MM_H__ */
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 xen/include/asm-powerpc/mm.h
--- a/xen/include/asm-powerpc/mm.h      Mon Mar 19 16:28:24 2007 +0000
+++ b/xen/include/asm-powerpc/mm.h      Mon Mar 19 16:48:24 2007 +0000
@@ -278,4 +278,6 @@ extern int steal_page(struct domain *d, 
 
 #define domain_clamp_alloc_bitsize(d, b) (b)
 
+#define domain_get_maximum_gpfn(d) (-ENOSYS)
+
 #endif
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Mon Mar 19 16:28:24 2007 +0000
+++ b/xen/include/asm-x86/mm.h  Mon Mar 19 16:48:24 2007 +0000
@@ -404,5 +404,6 @@ unsigned int domain_clamp_alloc_bitsize(
 # define domain_clamp_alloc_bitsize(d, b) (b)
 #endif
 
+unsigned long domain_get_maximum_gpfn(struct domain *d);
 
 #endif /* __ASM_X86_MM_H__ */
diff -r ed1e4cc4a5b7 -r 36e6f85cd572 xen/include/public/memory.h
--- a/xen/include/public/memory.h       Mon Mar 19 16:28:24 2007 +0000
+++ b/xen/include/public/memory.h       Mon Mar 19 16:48:24 2007 +0000
@@ -129,6 +129,11 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_excha
 #define XENMEM_maximum_reservation  4
 
 /*
+ * Returns the maximum GPFN in use by the guest, or -ve errcode on failure.
+ */
+#define XENMEM_maximum_gpfn         14
+
+/*
  * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
  * mapping table. Architectures which do not have a m2p table do not implement
  * this command.

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.