# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1179994495 -32400 # Node ID 1f567858b31f3694658def5bbae7c0289682b7f7 # Parent c4006953d0d12b2d06347c2f1c6f34ff49e0651f support save/restore with domain memmap. PATCHNAME: support_save_restore_with_memmap Signed-off-by: Isaku Yamahata diff -r c4006953d0d1 -r 1f567858b31f tools/libxc/ia64/xc_ia64_linux_restore.c --- a/tools/libxc/ia64/xc_ia64_linux_restore.c Mon May 21 16:47:47 2007 +0900 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Thu May 24 17:14:55 2007 +0900 @@ -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 c4006953d0d1 -r 1f567858b31f tools/libxc/ia64/xc_ia64_linux_save.c --- a/tools/libxc/ia64/xc_ia64_linux_save.c Mon May 21 16:47:47 2007 +0900 +++ b/tools/libxc/ia64/xc_ia64_linux_save.c Thu May 24 17:14:55 2007 +0900 @@ -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 c4006953d0d1 -r 1f567858b31f xen/arch/ia64/xen/dom0_ops.c --- a/xen/arch/ia64/xen/dom0_ops.c Mon May 21 16:47:47 2007 +0900 +++ b/xen/arch/ia64/xen/dom0_ops.c Thu May 24 17:14:55 2007 +0900 @@ -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 c4006953d0d1 -r 1f567858b31f xen/arch/ia64/xen/dom_fw_utils.c --- a/xen/arch/ia64/xen/dom_fw_utils.c Mon May 21 16:47:47 2007 +0900 +++ b/xen/arch/ia64/xen/dom_fw_utils.c Thu May 24 17:14:55 2007 +0900 @@ -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);