# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1180043692 21600
# Node ID c693c50a6ad510157613e3553e49b4191f3e8e76
# Parent 010370333a880c2a4a87f785c732b12f3a236d81
[IA64] memmap: save/restore: support save/restore with domain memmap
Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
tools/libxc/ia64/xc_ia64_linux_restore.c | 14 +++++--
tools/libxc/ia64/xc_ia64_linux_save.c | 60 +++++++++++++++----------------
xen/arch/ia64/xen/dom0_ops.c | 2 -
xen/arch/ia64/xen/dom_fw_utils.c | 14 +++++++
4 files changed, 56 insertions(+), 34 deletions(-)
diff -r 010370333a88 -r c693c50a6ad5 tools/libxc/ia64/xc_ia64_linux_restore.c
--- a/tools/libxc/ia64/xc_ia64_linux_restore.c Thu May 24 15:48:31 2007 -0600
+++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Thu May 24 15:54:52 2007 -0600
@@ -140,9 +140,7 @@ xc_domain_restore(int xc_handle, int io_
/* Build firmware (will be overwritten). */
domctl.domain = (domid_t)dom;
domctl.u.arch_setup.flags &= ~XEN_DOMAINSETUP_query;
- domctl.u.arch_setup.bp = ((p2m_size - 3) << PAGE_SHIFT)
- + sizeof (start_info_t);
- domctl.u.arch_setup.maxmem = (p2m_size - 3) << PAGE_SHIFT;
+ domctl.u.arch_setup.bp = 0; /* indicate domain restore */
domctl.cmd = XEN_DOMCTL_arch_setup;
if (xc_domctl(xc_handle, &domctl))
@@ -330,3 +328,13 @@ xc_domain_restore(int xc_handle, int io_
return rc;
}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 010370333a88 -r c693c50a6ad5 tools/libxc/ia64/xc_ia64_linux_save.c
--- a/tools/libxc/ia64/xc_ia64_linux_save.c Thu May 24 15:48:31 2007 -0600
+++ b/tools/libxc/ia64/xc_ia64_linux_save.c Thu May 24 15:54:52 2007 -0600
@@ -22,8 +22,8 @@
** XXX SMH: should consider if want to be able to override MAX_MBIT_RATE too.
**
*/
-#define DEF_MAX_ITERS (4 - 1) /* limit us to 4 times round loop */
-#define DEF_MAX_FACTOR 3 /* never send more than 3x nr_pfns */
+#define DEF_MAX_ITERS (4 - 1) /* limit us to 4 times round loop */
+#define DEF_MAX_FACTOR 3 /* never send more than 3x nr_pfns */
/*
** During (live) save/migrate, we maintain a number of bitmaps to track
@@ -37,23 +37,20 @@
#define BITMAP_SHIFT(_nr) ((_nr) % BITS_PER_LONG)
-static inline int test_bit (int nr, volatile void * addr)
+static inline int test_bit(int nr, volatile void * addr)
{
return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1;
}
-static inline void clear_bit (int nr, volatile void * addr)
+static inline void clear_bit(int nr, volatile void * addr)
{
BITMAP_ENTRY(nr, addr) &= ~(1UL << BITMAP_SHIFT(nr));
}
-static inline void set_bit ( int nr, volatile void * addr)
+static inline void set_bit(int nr, volatile void * addr)
{
BITMAP_ENTRY(nr, addr) |= (1UL << BITMAP_SHIFT(nr));
}
-
-/* total number of pages used by the current guest */
-static unsigned long max_pfn;
static int xc_ia64_shadow_control(int xc_handle,
uint32_t domid,
@@ -67,7 +64,7 @@ static int xc_ia64_shadow_control(int xc
unsigned char *bmap = (unsigned char *)dirty_bitmap;
unsigned long bmap_bytes =
((pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG - 1)) / 8;
- unsigned int bmap_pages = (bmap_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
+ unsigned int bmap_pages = (bmap_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
/* Touch the page so that it is in the TC.
FIXME: use a more reliable method. */
@@ -168,6 +165,9 @@ xc_domain_save(int xc_handle, int io_fd,
/* Number of pages sent (live only). */
unsigned int total_sent;
+ /* total number of pages used by the current guest */
+ unsigned long p2m_size;
+
/* Size of the shadow bitmap (live only). */
unsigned int bitmap_size = 0;
@@ -182,7 +182,7 @@ xc_domain_save(int xc_handle, int io_fd,
char *mem;
if (debug)
- fprintf (stderr, "xc_linux_save (ia64): started dom=%d\n", dom);
+ fprintf(stderr, "xc_linux_save (ia64): started dom=%d\n", dom);
/* If no explicit control parameters given, use defaults */
if (!max_iters)
@@ -216,17 +216,17 @@ xc_domain_save(int xc_handle, int io_fd,
goto out;
}
- max_pfn = info.max_memkb >> (PAGE_SHIFT - 10);
-
- page_array = malloc(max_pfn * sizeof(unsigned long));
+ p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom);
+
+ page_array = malloc(p2m_size * sizeof(unsigned long));
if (page_array == NULL) {
ERROR("Could not allocate memory");
goto out;
}
/* This is expected by xm restore. */
- if (!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) {
- ERROR("write: max_pfn");
+ if (!write_exact(io_fd, &p2m_size, sizeof(unsigned long))) {
+ ERROR("write: p2m_size");
goto out;
}
@@ -269,7 +269,7 @@ xc_domain_save(int xc_handle, int io_fd,
last_iter = 0;
- bitmap_size = ((max_pfn + BITS_PER_LONG-1) & ~(BITS_PER_LONG-1)) / 8;
+ bitmap_size = ((p2m_size + BITS_PER_LONG-1) & ~(BITS_PER_LONG-1)) / 8;
to_send = malloc(bitmap_size);
to_skip = malloc(bitmap_size);
@@ -289,7 +289,7 @@ xc_domain_save(int xc_handle, int io_fd,
ERROR("Unable to lock_pages to_skip");
goto out;
}
-
+
} else {
/* This is a non-live suspend. Issue the call back to get the
@@ -304,7 +304,7 @@ xc_domain_save(int xc_handle, int io_fd,
}
- sent_last_iter = max_pfn;
+ sent_last_iter = p2m_size;
total_sent = 0;
for (iter = 1; ; iter++) {
@@ -316,7 +316,7 @@ xc_domain_save(int xc_handle, int io_fd,
/* Get the pfn list, as it may change. */
if (xc_ia64_get_pfn_list(xc_handle, dom, page_array,
- 0, max_pfn) != max_pfn) {
+ 0, p2m_size) != p2m_size) {
ERROR("Could not get the page frame list");
goto out;
}
@@ -327,14 +327,14 @@ xc_domain_save(int xc_handle, int io_fd,
if (!last_iter) {
if (xc_ia64_shadow_control(xc_handle, dom,
XEN_DOMCTL_SHADOW_OP_PEEK,
- to_skip, max_pfn, NULL) != max_pfn) {
+ to_skip, p2m_size, NULL) != p2m_size) {
ERROR("Error peeking shadow bitmap");
goto out;
}
}
/* Start writing out the saved-domain record. */
- for (N = 0; N < max_pfn; N++) {
+ for (N = 0; N < p2m_size; N++) {
if (page_array[N] == INVALID_MFN)
continue;
if (!last_iter) {
@@ -346,7 +346,7 @@ xc_domain_save(int xc_handle, int io_fd,
if (debug)
fprintf(stderr, "xc_linux_save: page %lx (%lu/%lu)\n",
- page_array[N], N, max_pfn);
+ page_array[N], N, p2m_size);
mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE, N);
@@ -360,7 +360,7 @@ xc_domain_save(int xc_handle, int io_fd,
}
if (!write_exact(io_fd, &N, sizeof(N))) {
- ERROR("write: max_pfn");
+ ERROR("write: p2m_size");
munmap(mem, PAGE_SIZE);
goto out;
}
@@ -384,7 +384,7 @@ xc_domain_save(int xc_handle, int io_fd,
if (live) {
if ( /* ((sent_this_iter > sent_last_iter) && RATE_IS_MAX()) || */
(iter >= max_iters) || (sent_this_iter+skip_this_iter < 50) ||
- (total_sent > max_pfn*max_factor)) {
+ (total_sent > p2m_size*max_factor)) {
DPRINTF("Start last iteration\n");
last_iter = 1;
@@ -397,7 +397,7 @@ xc_domain_save(int xc_handle, int io_fd,
/* Pages to be sent are pages which were dirty. */
if (xc_ia64_shadow_control(xc_handle, dom,
XEN_DOMCTL_SHADOW_OP_CLEAN,
- to_send, max_pfn, NULL ) != max_pfn) {
+ to_send, p2m_size, NULL ) != p2m_size) {
ERROR("Error flushing shadow PT");
goto out;
}
@@ -409,7 +409,7 @@ xc_domain_save(int xc_handle, int io_fd,
}
- fprintf (stderr, "All memory is saved\n");
+ fprintf(stderr, "All memory is saved\n");
/* terminate */
{
@@ -425,7 +425,7 @@ xc_domain_save(int xc_handle, int io_fd,
unsigned int i,j;
unsigned long pfntab[1024];
- for (i = 0, j = 0; i < max_pfn; i++) {
+ for (i = 0, j = 0; i < p2m_size; i++) {
if (page_array[i] == INVALID_MFN)
j++;
}
@@ -435,13 +435,13 @@ xc_domain_save(int xc_handle, int io_fd,
goto out;
}
- for (i = 0, j = 0; i < max_pfn; ) {
+ for (i = 0, j = 0; i < p2m_size; ) {
if (page_array[i] == INVALID_MFN)
pfntab[j++] = i;
i++;
- if (j == 1024 || i == max_pfn) {
+ if (j == 1024 || i == p2m_size) {
if (!write_exact(io_fd, &pfntab, sizeof(unsigned long)*j)) {
ERROR("Error when writing to state file (6b)");
goto out;
@@ -475,7 +475,7 @@ xc_domain_save(int xc_handle, int io_fd,
munmap(mem, PAGE_SIZE);
goto out;
}
- munmap(mem, PAGE_SIZE);
+ munmap(mem, PAGE_SIZE);
if (!write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
ERROR("Error when writing to state file (1)");
diff -r 010370333a88 -r c693c50a6ad5 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c Thu May 24 15:48:31 2007 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c Thu May 24 15:54:52 2007 -0600
@@ -89,7 +89,7 @@ long arch_do_domctl(xen_domctl_t *op, XE
ds->flags |= XEN_DOMAINSETUP_hvm_guest;
/* Set params. */
ds->bp = 0; /* unknown. */
- ds->maxmem = 0; /* unknown. */
+ ds->maxmem = d->arch.convmem_end;
ds->xsi_va = d->arch.shared_info_va;
ds->hypercall_imm = d->arch.breakimm;
/* Copy back. */
diff -r 010370333a88 -r c693c50a6ad5 xen/arch/ia64/xen/dom_fw_utils.c
--- a/xen/arch/ia64/xen/dom_fw_utils.c Thu May 24 15:48:31 2007 -0600
+++ b/xen/arch/ia64/xen/dom_fw_utils.c Thu May 24 15:54:52 2007 -0600
@@ -139,6 +139,14 @@ assign_new_domain_page_if_dom0(struct do
assign_new_domain0_page(d, mpaddr);
}
+static void
+dom_fw_setup_for_domain_restore(domain_t *d, unsigned long maxmem)
+{
+ assign_new_domain_page(d, FW_HYPERCALL_BASE_PADDR);
+ dom_fw_domain_init(d, domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR));
+ d->arch.convmem_end = maxmem;
+}
+
int
dom_fw_setup(domain_t *d, unsigned long bp_mpa, unsigned long maxmem)
{
@@ -148,6 +156,12 @@ dom_fw_setup(domain_t *d, unsigned long
BUILD_BUG_ON(sizeof(struct fw_tables) >
(FW_TABLES_END_PADDR - FW_TABLES_BASE_PADDR));
+
+ if (bp_mpa == 0) {
+ /* bp_mpa == 0 means this is domain restore case. */
+ dom_fw_setup_for_domain_restore(d, maxmem);
+ return 0;
+ }
/* Create page for boot_param. */
assign_new_domain_page_if_dom0(d, bp_mpa);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|