# 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
|