[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Save/restore: disentangle max_pfn from nr_pages.
# HG changeset patch # User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx> # Date 1171018121 0 # Node ID d39e8c44da34ac257b26cce29122852ef3a930cc # Parent dda3e75f015d31251c8e4cd22958276a2403a945 [HVM] Save/restore: disentangle max_pfn from nr_pages. These have been used interchangeably, which is OK for PV domains but not for HVM. This fixes an over-allocation by 256MB when restoring HVM guests that have more than 4GB of RAM. Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx> --- tools/libxc/xc_hvm_restore.c | 60 ++++++++++++++++++++----------------------- tools/libxc/xenguest.h | 2 - tools/libxc/xg_private.c | 2 - tools/xcutils/xc_restore.c | 10 +++---- 4 files changed, 35 insertions(+), 39 deletions(-) diff -r dda3e75f015d -r d39e8c44da34 tools/libxc/xc_hvm_restore.c --- a/tools/libxc/xc_hvm_restore.c Fri Feb 09 10:21:12 2007 +0000 +++ b/tools/libxc/xc_hvm_restore.c Fri Feb 09 10:48:41 2007 +0000 @@ -41,11 +41,8 @@ static unsigned long hvirt_start; /* #levels of page tables used by the currrent guest */ static unsigned int pt_levels; -/* total number of pages used by the current guest */ -static unsigned long max_pfn; - -/* A table mapping each PFN to its new MFN. */ -static xen_pfn_t *p2m = NULL; +/* A list of PFNs that exist, used when allocating memory to the guest */ +static xen_pfn_t *pfns = NULL; static ssize_t read_exact(int fd, void *buf, size_t count) @@ -67,7 +64,7 @@ read_exact(int fd, void *buf, size_t cou } int xc_hvm_restore(int xc_handle, int io_fd, - uint32_t dom, unsigned long nr_pfns, + uint32_t dom, unsigned long max_pfn, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int pae, unsigned int apic) { @@ -90,7 +87,7 @@ int xc_hvm_restore(int xc_handle, int io unsigned long long v_end, memsize; unsigned long shared_page_nr; - unsigned long mfn, pfn; + unsigned long pfn; unsigned int prev_pc, this_pc; int verify = 0; @@ -98,23 +95,27 @@ int xc_hvm_restore(int xc_handle, int io 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; /* hvm guest mem size (Mb) */ memsize = (unsigned long long)*store_mfn; v_end = memsize << 20; - - DPRINTF("xc_hvm_restore:dom=%d, nr_pfns=0x%lx, store_evtchn=%d, *store_mfn=%ld, pae=%u, apic=%u.\n", - dom, nr_pfns, store_evtchn, *store_mfn, pae, apic); - - max_pfn = nr_pfns; - + nr_pages = (unsigned long) memsize << (20 - PAGE_SHIFT); + + DPRINTF("xc_hvm_restore:dom=%d, nr_pages=0x%lx, store_evtchn=%d, *store_mfn=%ld, pae=%u, apic=%u.\n", + dom, nr_pages, store_evtchn, *store_mfn, pae, apic); + + if(!get_platform_info(xc_handle, dom, &max_mfn, &hvirt_start, &pt_levels)) { ERROR("Unable to get platform info."); return 1; } - DPRINTF("xc_hvm_restore start: max_pfn = %lx, max_mfn = %lx, hvirt_start=%lx, pt_levels=%d\n", + DPRINTF("xc_hvm_restore start: nr_pages = %lx, max_pfn = %lx, max_mfn = %lx, hvirt_start=%lx, pt_levels=%d\n", + nr_pages, max_pfn, max_mfn, hvirt_start, @@ -127,30 +128,30 @@ int xc_hvm_restore(int xc_handle, int io } - p2m = malloc(max_pfn * sizeof(xen_pfn_t)); - if (p2m == NULL) { + pfns = malloc(max_pfn * sizeof(xen_pfn_t)); + if (pfns == NULL) { ERROR("memory alloc failed"); errno = ENOMEM; goto out; } - if(xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(max_pfn)) != 0) { + if(xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(nr_pages)) != 0) { errno = ENOMEM; goto out; } for ( i = 0; i < max_pfn; i++ ) - p2m[i] = i; + pfns[i] = i; for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < max_pfn; i++ ) - p2m[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; + pfns[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */ rc = xc_domain_memory_populate_physmap( - xc_handle, dom, (max_pfn > 0xa0) ? 0xa0 : max_pfn, - 0, 0, &p2m[0x00]); - if ( (rc == 0) && (max_pfn > 0xc0) ) + xc_handle, dom, (nr_pages > 0xa0) ? 0xa0 : nr_pages, + 0, 0, &pfns[0x00]); + if ( (rc == 0) && (nr_pages > 0xc0) ) rc = xc_domain_memory_populate_physmap( - xc_handle, dom, max_pfn - 0xc0, 0, 0, &p2m[0xc0]); + xc_handle, dom, nr_pages - 0xc0, 0, 0, &pfns[0xc0]); if ( rc != 0 ) { PERROR("Could not allocate memory for HVM guest.\n"); @@ -171,9 +172,6 @@ int xc_hvm_restore(int xc_handle, int io goto out; } - for ( i = 0; i < max_pfn; i++) - p2m[i] = i; - prev_pc = 0; n = 0; @@ -181,7 +179,7 @@ int xc_hvm_restore(int xc_handle, int io int j; - this_pc = (n * 100) / max_pfn; + this_pc = (n * 100) / nr_pages; if ( (this_pc - prev_pc) >= 5 ) { PPRINTF("\b\b\b\b%3d%%", this_pc); @@ -234,8 +232,6 @@ int xc_hvm_restore(int xc_handle, int io } - mfn = p2m[pfn]; - /* In verify mode, we use a copy; otherwise we work in place */ page = verify ? (void *)buf : (region_base + i*PAGE_SIZE); @@ -252,8 +248,8 @@ int xc_hvm_restore(int xc_handle, int io int v; - DPRINTF("************** pfn=%lx mfn=%lx gotcs=%08lx " - "actualcs=%08lx\n", pfn, p2m[pfn], + DPRINTF("************** pfn=%lx gotcs=%08lx " + "actualcs=%08lx\n", pfn, csum_page(region_base + i*PAGE_SIZE), csum_page(buf)); @@ -361,7 +357,7 @@ int xc_hvm_restore(int xc_handle, int io out: if ( (rc != 0) && (dom != 0) ) xc_domain_destroy(xc_handle, dom); - free(p2m); + free(pfns); free(hvm_buf); DPRINTF("Restore exit with rc=%d\n", rc); diff -r dda3e75f015d -r d39e8c44da34 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Fri Feb 09 10:21:12 2007 +0000 +++ b/tools/libxc/xenguest.h Fri Feb 09 10:48:41 2007 +0000 @@ -57,7 +57,7 @@ int xc_linux_restore(int xc_handle, int * @return 0 on success, -1 on failure */ int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom, - unsigned long nr_pfns, unsigned int store_evtchn, + unsigned long max_pfn, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int pae, unsigned int apic); diff -r dda3e75f015d -r d39e8c44da34 tools/libxc/xg_private.c --- a/tools/libxc/xg_private.c Fri Feb 09 10:21:12 2007 +0000 +++ b/tools/libxc/xg_private.c Fri Feb 09 10:48:41 2007 +0000 @@ -209,7 +209,7 @@ int xc_hvm_save(int xc_handle, int io_fd __attribute__((weak)) int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom, - unsigned long nr_pfns, unsigned int store_evtchn, + unsigned long max_pfn, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int pae, unsigned int apic) { diff -r dda3e75f015d -r d39e8c44da34 tools/xcutils/xc_restore.c --- a/tools/xcutils/xc_restore.c Fri Feb 09 10:21:12 2007 +0000 +++ b/tools/xcutils/xc_restore.c Fri Feb 09 10:48:41 2007 +0000 @@ -18,14 +18,14 @@ int int main(int argc, char **argv) { - unsigned int xc_fd, io_fd, domid, nr_pfns, store_evtchn, console_evtchn; + unsigned int xc_fd, io_fd, domid, max_pfn, store_evtchn, console_evtchn; unsigned int hvm, pae, apic; int ret; unsigned long store_mfn, console_mfn; if (argc != 9) errx(1, - "usage: %s iofd domid nr_pfns store_evtchn console_evtchn hvm pae apic", + "usage: %s iofd domid max_pfn store_evtchn console_evtchn hvm pae apic", argv[0]); xc_fd = xc_interface_open(); @@ -34,7 +34,7 @@ main(int argc, char **argv) io_fd = atoi(argv[1]); domid = atoi(argv[2]); - nr_pfns = atoi(argv[3]); + max_pfn = atoi(argv[3]); store_evtchn = atoi(argv[4]); console_evtchn = atoi(argv[5]); hvm = atoi(argv[6]); @@ -44,10 +44,10 @@ main(int argc, char **argv) if (hvm) { /* pass the memsize to xc_hvm_restore to find the store_mfn */ store_mfn = hvm; - ret = xc_hvm_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn, + ret = xc_hvm_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn, &store_mfn, pae, apic); } else - ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn, + ret = xc_linux_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn, &store_mfn, console_evtchn, &console_mfn); if (ret == 0) { _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |