ia64/xen-unstable
changeset 15846:e7c143aafbc1
[IA64] Foreign p2m: rewrite save/restore with foreign p2m
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author | Alex Williamson <alex.williamson@hp.com> |
---|---|
date | Thu Sep 06 15:36:13 2007 -0600 (2007-09-06) |
parents | de247793f7b5 |
children | 192f2df46e67 |
files | tools/libxc/ia64/xc_ia64_linux_restore.c tools/libxc/ia64/xc_ia64_linux_save.c tools/libxc/ia64/xc_ia64_save_restore.h |
line diff
1.1 --- a/tools/libxc/ia64/xc_ia64_linux_restore.c Thu Sep 06 15:32:54 2007 -0600 1.2 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Thu Sep 06 15:36:13 2007 -0600 1.3 @@ -5,12 +5,18 @@ 1.4 * 1.5 * Copyright (c) 2003, K A Fraser. 1.6 * Rewritten for ia64 by Tristan Gingold <tristan.gingold@bull.net> 1.7 + * 1.8 + * Copyright (c) 2007 Isaku Yamahata <yamahata@valinux.co.jp> 1.9 + * Use foreign p2m exposure. 1.10 */ 1.11 1.12 #include <stdlib.h> 1.13 #include <unistd.h> 1.14 1.15 #include "xg_private.h" 1.16 +#include "xc_ia64_save_restore.h" 1.17 +#include "xc_ia64.h" 1.18 +#include "xc_efi.h" 1.19 1.20 #define PFN_TO_KB(_pfn) ((_pfn) << (PAGE_SHIFT - 10)) 1.21 1.22 @@ -40,6 +46,16 @@ read_exact(int fd, void *buf, size_t cou 1.23 } 1.24 1.25 static int 1.26 +populate_page_if_necessary(int xc_handle, uint32_t dom, unsigned long gmfn, 1.27 + struct xen_ia64_p2m_table *p2m_table) 1.28 +{ 1.29 + if (xc_ia64_p2m_present(p2m_table, gmfn)) 1.30 + return 0; 1.31 + 1.32 + return xc_domain_memory_populate_physmap(xc_handle, dom, 1, 0, 0, &gmfn); 1.33 +} 1.34 + 1.35 +static int 1.36 read_page(int xc_handle, int io_fd, uint32_t dom, unsigned long pfn) 1.37 { 1.38 void *mem; 1.39 @@ -66,7 +82,8 @@ xc_domain_restore(int xc_handle, int io_ 1.40 unsigned int hvm, unsigned int pae) 1.41 { 1.42 DECLARE_DOMCTL; 1.43 - int rc = 1, i; 1.44 + int rc = 1; 1.45 + unsigned int i; 1.46 unsigned long gmfn; 1.47 unsigned long ver; 1.48 1.49 @@ -78,11 +95,12 @@ xc_domain_restore(int xc_handle, int io_ 1.50 /* A copy of the CPU context of the guest. */ 1.51 vcpu_guest_context_t ctxt; 1.52 1.53 - unsigned long *page_array = NULL; 1.54 - 1.55 /* A temporary mapping of the guest's start_info page. */ 1.56 start_info_t *start_info; 1.57 1.58 + struct xen_ia64_p2m_table p2m_table; 1.59 + xc_ia64_p2m_init(&p2m_table); 1.60 + 1.61 if (hvm) { 1.62 ERROR("HVM Restore is unsupported"); 1.63 goto out; 1.64 @@ -102,7 +120,7 @@ xc_domain_restore(int xc_handle, int io_ 1.65 ERROR("Error when reading version"); 1.66 goto out; 1.67 } 1.68 - if (ver != 1) { 1.69 + if (ver != XC_IA64_SR_FORMAT_VER_ONE && ver != XC_IA64_SR_FORMAT_VER_TWO) { 1.70 ERROR("version of save doesn't match"); 1.71 goto out; 1.72 } 1.73 @@ -113,25 +131,6 @@ xc_domain_restore(int xc_handle, int io_ 1.74 return 1; 1.75 } 1.76 1.77 - /* Get pages. */ 1.78 - page_array = malloc(p2m_size * sizeof(unsigned long)); 1.79 - if (page_array == NULL) { 1.80 - ERROR("Could not allocate memory"); 1.81 - goto out; 1.82 - } 1.83 - 1.84 - for ( i = 0; i < p2m_size; i++ ) 1.85 - page_array[i] = i; 1.86 - 1.87 - if ( xc_domain_memory_populate_physmap(xc_handle, dom, p2m_size, 1.88 - 0, 0, page_array) ) 1.89 - { 1.90 - ERROR("Failed to allocate memory for %ld KB to dom %d.\n", 1.91 - PFN_TO_KB(p2m_size), dom); 1.92 - goto out; 1.93 - } 1.94 - DPRINTF("Allocated memory by %ld KB\n", PFN_TO_KB(p2m_size)); 1.95 - 1.96 if (!read_exact(io_fd, &domctl.u.arch_setup, sizeof(domctl.u.arch_setup))) { 1.97 ERROR("read: domain setup"); 1.98 goto out; 1.99 @@ -155,6 +154,61 @@ xc_domain_restore(int xc_handle, int io_ 1.100 } 1.101 shared_info_frame = domctl.u.getdomaininfo.shared_info_frame; 1.102 1.103 + if (ver == XC_IA64_SR_FORMAT_VER_TWO) { 1.104 + unsigned int memmap_info_num_pages; 1.105 + unsigned long memmap_size; 1.106 + xen_ia64_memmap_info_t *memmap_info; 1.107 + 1.108 + if (!read_exact(io_fd, &memmap_info_num_pages, 1.109 + sizeof(memmap_info_num_pages))) { 1.110 + ERROR("read: memmap_info_num_pages"); 1.111 + goto out; 1.112 + } 1.113 + memmap_size = memmap_info_num_pages * PAGE_SIZE; 1.114 + memmap_info = malloc(memmap_size); 1.115 + if (memmap_info == NULL) { 1.116 + ERROR("Could not allocate memory for memmap_info"); 1.117 + goto out; 1.118 + } 1.119 + if (!read_exact(io_fd, memmap_info, memmap_size)) { 1.120 + ERROR("read: memmap_info"); 1.121 + goto out; 1.122 + } 1.123 + if (xc_ia64_p2m_map(&p2m_table, xc_handle, 1.124 + dom, memmap_info, IA64_DOM0VP_EFP_ALLOC_PTE)) { 1.125 + ERROR("p2m mapping"); 1.126 + goto out; 1.127 + } 1.128 + free(memmap_info); 1.129 + } else if (ver == XC_IA64_SR_FORMAT_VER_ONE) { 1.130 + xen_ia64_memmap_info_t *memmap_info; 1.131 + efi_memory_desc_t *memdesc; 1.132 + uint64_t buffer[(sizeof(*memmap_info) + sizeof(*memdesc) + 1.133 + sizeof(uint64_t) - 1) / sizeof(uint64_t)]; 1.134 + 1.135 + memset(buffer, 0, sizeof(buffer)); 1.136 + memmap_info = (xen_ia64_memmap_info_t *)buffer; 1.137 + memdesc = (efi_memory_desc_t*)&memmap_info->memdesc[0]; 1.138 + memmap_info->efi_memmap_size = sizeof(*memmap_info) + sizeof(*memdesc); 1.139 + memmap_info->efi_memdesc_size = sizeof(*memdesc); 1.140 + memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION; 1.141 + 1.142 + memdesc->type = EFI_MEMORY_DESCRIPTOR_VERSION; 1.143 + memdesc->phys_addr = 0; 1.144 + memdesc->virt_addr = 0; 1.145 + memdesc->num_pages = nr_pfns << (PAGE_SHIFT - EFI_PAGE_SHIFT); 1.146 + memdesc->attribute = EFI_MEMORY_WB; 1.147 + 1.148 + if (xc_ia64_p2m_map(&p2m_table, xc_handle, 1.149 + dom, memmap_info, IA64_DOM0VP_EFP_ALLOC_PTE)) { 1.150 + ERROR("p2m mapping"); 1.151 + goto out; 1.152 + } 1.153 + } else { 1.154 + ERROR("unknown version"); 1.155 + goto out; 1.156 + } 1.157 + 1.158 DPRINTF("Reloading memory pages: 0%%\n"); 1.159 1.160 while (1) { 1.161 @@ -165,17 +219,26 @@ xc_domain_restore(int xc_handle, int io_ 1.162 if (gmfn == INVALID_MFN) 1.163 break; 1.164 1.165 + if (populate_page_if_necessary(xc_handle, dom, gmfn, &p2m_table) < 0) { 1.166 + ERROR("can not populate page 0x%lx", gmfn); 1.167 + goto out; 1.168 + } 1.169 if (read_page(xc_handle, io_fd, dom, gmfn) < 0) 1.170 goto out; 1.171 } 1.172 1.173 DPRINTF("Received all pages\n"); 1.174 1.175 - /* Get the list of PFNs that are not in the psuedo-phys map */ 1.176 + /* 1.177 + * Get the list of PFNs that are not in the psuedo-phys map. 1.178 + * Although we allocate pages on demand, balloon driver may 1.179 + * decreased simaltenously. So we have to free the freed 1.180 + * pages here. 1.181 + */ 1.182 { 1.183 unsigned int count; 1.184 unsigned long *pfntab; 1.185 - int rc; 1.186 + unsigned int nr_frees; 1.187 1.188 if (!read_exact(io_fd, &count, sizeof(count))) { 1.189 ERROR("Error when reading pfn count"); 1.190 @@ -190,36 +253,31 @@ xc_domain_restore(int xc_handle, int io_ 1.191 1.192 if (!read_exact(io_fd, pfntab, sizeof(unsigned long)*count)) { 1.193 ERROR("Error when reading pfntab"); 1.194 + free(pfntab); 1.195 goto out; 1.196 } 1.197 1.198 - DPRINTF ("Try to free %u pages\n", count); 1.199 - 1.200 + nr_frees = 0; 1.201 for (i = 0; i < count; i++) { 1.202 - 1.203 - volatile unsigned long pfn; 1.204 - 1.205 - struct xen_memory_reservation reservation = { 1.206 - .nr_extents = 1, 1.207 - .extent_order = 0, 1.208 - .domid = dom 1.209 - }; 1.210 - set_xen_guest_handle(reservation.extent_start, 1.211 - (unsigned long *)&pfn); 1.212 - 1.213 - pfn = pfntab[i]; 1.214 - rc = xc_memory_op(xc_handle, XENMEM_decrease_reservation, 1.215 - &reservation); 1.216 - if (rc != 1) { 1.217 + if (xc_ia64_p2m_allocated(&p2m_table, pfntab[i])) { 1.218 + pfntab[nr_frees] = pfntab[i]; 1.219 + nr_frees++; 1.220 + } 1.221 + } 1.222 + if (nr_frees > 0) { 1.223 + if (xc_domain_memory_decrease_reservation(xc_handle, dom, nr_frees, 1.224 + 0, pfntab) < 0) { 1.225 ERROR("Could not decrease reservation : %d", rc); 1.226 + free(pfntab); 1.227 goto out; 1.228 } 1.229 + else 1.230 + DPRINTF("Decreased reservation by %d / %d pages\n", 1.231 + nr_frees, count); 1.232 } 1.233 - 1.234 - DPRINTF("Decreased reservation by %d pages\n", count); 1.235 + free(pfntab); 1.236 } 1.237 1.238 - 1.239 if (!read_exact(io_fd, &ctxt, sizeof(ctxt))) { 1.240 ERROR("Error when reading ctxt"); 1.241 goto out; 1.242 @@ -274,6 +332,10 @@ xc_domain_restore(int xc_handle, int io_ 1.243 munmap (shared_info, PAGE_SIZE); 1.244 1.245 /* Uncanonicalise the suspend-record frame number and poke resume rec. */ 1.246 + if (populate_page_if_necessary(xc_handle, dom, gmfn, &p2m_table)) { 1.247 + ERROR("cannot populate page 0x%lx", gmfn); 1.248 + goto out; 1.249 + } 1.250 start_info = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 1.251 PROT_READ | PROT_WRITE, gmfn); 1.252 if (start_info == NULL) { 1.253 @@ -309,8 +371,7 @@ xc_domain_restore(int xc_handle, int io_ 1.254 if ((rc != 0) && (dom != 0)) 1.255 xc_domain_destroy(xc_handle, dom); 1.256 1.257 - if (page_array != NULL) 1.258 - free(page_array); 1.259 + xc_ia64_p2m_unmap(&p2m_table); 1.260 1.261 unlock_pages(&ctxt, sizeof(ctxt)); 1.262
2.1 --- a/tools/libxc/ia64/xc_ia64_linux_save.c Thu Sep 06 15:32:54 2007 -0600 2.2 +++ b/tools/libxc/ia64/xc_ia64_linux_save.c Thu Sep 06 15:36:13 2007 -0600 2.3 @@ -5,6 +5,9 @@ 2.4 * 2.5 * Copyright (c) 2003, K A Fraser. 2.6 * Rewritten for ia64 by Tristan Gingold <tristan.gingold@bull.net> 2.7 + * 2.8 + * Copyright (c) 2007 Isaku Yamahata <yamahata@valinux.co.jp> 2.9 + * Use foreign p2m exposure. 2.10 */ 2.11 2.12 #include <inttypes.h> 2.13 @@ -14,6 +17,9 @@ 2.14 #include <sys/time.h> 2.15 2.16 #include "xg_private.h" 2.17 +#include "xc_ia64.h" 2.18 +#include "xc_ia64_save_restore.h" 2.19 +#include "xc_efi.h" 2.20 2.21 /* 2.22 ** Default values for important tuning parameters. Can override by passing 2.23 @@ -151,8 +157,6 @@ xc_domain_save(int xc_handle, int io_fd, 2.24 /* A copy of the CPU context of the guest. */ 2.25 vcpu_guest_context_t ctxt; 2.26 2.27 - unsigned long *page_array = NULL; 2.28 - 2.29 /* Live mapping of shared info structure */ 2.30 shared_info_t *live_shinfo = NULL; 2.31 2.32 @@ -181,6 +185,17 @@ xc_domain_save(int xc_handle, int io_fd, 2.33 2.34 char *mem; 2.35 2.36 + unsigned int memmap_info_num_pages; 2.37 + unsigned long memmap_size = 0; 2.38 + xen_ia64_memmap_info_t *memmap_info_live = NULL; 2.39 + xen_ia64_memmap_info_t *memmap_info = NULL; 2.40 + void *memmap_desc_start; 2.41 + void *memmap_desc_end; 2.42 + void *p; 2.43 + efi_memory_desc_t *md; 2.44 + struct xen_ia64_p2m_table p2m_table; 2.45 + xc_ia64_p2m_init(&p2m_table); 2.46 + 2.47 if (debug) 2.48 fprintf(stderr, "xc_linux_save (ia64): started dom=%d\n", dom); 2.49 2.50 @@ -218,12 +233,6 @@ xc_domain_save(int xc_handle, int io_fd, 2.51 2.52 p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom); 2.53 2.54 - page_array = malloc(p2m_size * sizeof(unsigned long)); 2.55 - if (page_array == NULL) { 2.56 - ERROR("Could not allocate memory"); 2.57 - goto out; 2.58 - } 2.59 - 2.60 /* This is expected by xm restore. */ 2.61 if (!write_exact(io_fd, &p2m_size, sizeof(unsigned long))) { 2.62 ERROR("write: p2m_size"); 2.63 @@ -236,7 +245,7 @@ xc_domain_save(int xc_handle, int io_fd, 2.64 The version is hard-coded, don't forget to change the restore code 2.65 too! */ 2.66 { 2.67 - unsigned long version = 1; 2.68 + unsigned long version = XC_IA64_SR_FORMAT_VER_CURRENT; 2.69 2.70 if (!write_exact(io_fd, &version, sizeof(unsigned long))) { 2.71 ERROR("write: version"); 2.72 @@ -304,6 +313,38 @@ xc_domain_save(int xc_handle, int io_fd, 2.73 2.74 } 2.75 2.76 + memmap_info_num_pages = live_shinfo->arch.memmap_info_num_pages; 2.77 + memmap_size = PAGE_SIZE * memmap_info_num_pages; 2.78 + memmap_info_live = xc_map_foreign_range(xc_handle, info.domid, 2.79 + memmap_size, PROT_READ, 2.80 + live_shinfo->arch.memmap_info_pfn); 2.81 + if (memmap_info_live == NULL) { 2.82 + PERROR("Could not map memmap info."); 2.83 + goto out; 2.84 + } 2.85 + memmap_info = malloc(memmap_size); 2.86 + if (memmap_info == NULL) { 2.87 + PERROR("Could not allocate memmap info memory"); 2.88 + goto out; 2.89 + } 2.90 + memcpy(memmap_info, memmap_info_live, memmap_size); 2.91 + munmap(memmap_info_live, memmap_size); 2.92 + memmap_info_live = NULL; 2.93 + 2.94 + if (xc_ia64_p2m_map(&p2m_table, xc_handle, dom, memmap_info, 0) < 0) { 2.95 + PERROR("xc_ia64_p2m_map"); 2.96 + goto out; 2.97 + } 2.98 + if (!write_exact(io_fd, 2.99 + &memmap_info_num_pages, sizeof(memmap_info_num_pages))) { 2.100 + PERROR("write: arch.memmap_info_num_pages"); 2.101 + goto out; 2.102 + } 2.103 + if (!write_exact(io_fd, memmap_info, memmap_size)) { 2.104 + PERROR("write: memmap_info"); 2.105 + goto out; 2.106 + } 2.107 + 2.108 sent_last_iter = p2m_size; 2.109 total_sent = 0; 2.110 2.111 @@ -314,13 +355,6 @@ xc_domain_save(int xc_handle, int io_fd, 2.112 sent_this_iter = 0; 2.113 skip_this_iter = 0; 2.114 2.115 - /* Get the pfn list, as it may change. */ 2.116 - if (xc_ia64_get_pfn_list(xc_handle, dom, page_array, 2.117 - 0, p2m_size) != p2m_size) { 2.118 - ERROR("Could not get the page frame list"); 2.119 - goto out; 2.120 - } 2.121 - 2.122 /* Dirtied pages won't be saved. 2.123 slightly wasteful to peek the whole array evey time, 2.124 but this is fast enough for the moment. */ 2.125 @@ -334,45 +368,64 @@ xc_domain_save(int xc_handle, int io_fd, 2.126 } 2.127 2.128 /* Start writing out the saved-domain record. */ 2.129 - for (N = 0; N < p2m_size; N++) { 2.130 - if (page_array[N] == INVALID_MFN) 2.131 + memmap_desc_start = &memmap_info->memdesc; 2.132 + memmap_desc_end = memmap_desc_start + memmap_info->efi_memmap_size; 2.133 + for (p = memmap_desc_start; 2.134 + p < memmap_desc_end; 2.135 + p += memmap_info->efi_memdesc_size) { 2.136 + md = p; 2.137 + if (md->type != EFI_CONVENTIONAL_MEMORY || 2.138 + md->attribute != EFI_MEMORY_WB || 2.139 + md->num_pages == 0) 2.140 continue; 2.141 - if (!last_iter) { 2.142 - if (test_bit(N, to_skip) && test_bit(N, to_send)) 2.143 - skip_this_iter++; 2.144 - if (test_bit(N, to_skip) || !test_bit(N, to_send)) 2.145 + 2.146 + for (N = md->phys_addr >> PAGE_SHIFT; 2.147 + N < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> 2.148 + PAGE_SHIFT; 2.149 + N++) { 2.150 + 2.151 + if (!xc_ia64_p2m_allocated(&p2m_table, N)) 2.152 continue; 2.153 - } 2.154 2.155 - if (debug) 2.156 - fprintf(stderr, "xc_linux_save: page %lx (%lu/%lu)\n", 2.157 - page_array[N], N, p2m_size); 2.158 + if (!last_iter) { 2.159 + if (test_bit(N, to_skip) && test_bit(N, to_send)) 2.160 + skip_this_iter++; 2.161 + if (test_bit(N, to_skip) || !test_bit(N, to_send)) 2.162 + continue; 2.163 + } 2.164 2.165 - mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 2.166 - PROT_READ|PROT_WRITE, N); 2.167 - if (mem == NULL) { 2.168 - /* The page may have move. 2.169 - It will be remarked dirty. 2.170 - FIXME: to be tracked. */ 2.171 - fprintf(stderr, "cannot map mfn page %lx gpfn %lx: %s\n", 2.172 - page_array[N], N, safe_strerror(errno)); 2.173 - continue; 2.174 - } 2.175 + if (debug) 2.176 + fprintf(stderr, "xc_linux_save: page %lx (%lu/%lu)\n", 2.177 + xc_ia64_p2m_mfn(&p2m_table, N), 2.178 + N, p2m_size); 2.179 2.180 - if (!write_exact(io_fd, &N, sizeof(N))) { 2.181 - ERROR("write: p2m_size"); 2.182 - munmap(mem, PAGE_SIZE); 2.183 - goto out; 2.184 - } 2.185 + mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 2.186 + PROT_READ|PROT_WRITE, N); 2.187 + if (mem == NULL) { 2.188 + /* The page may have move. 2.189 + It will be remarked dirty. 2.190 + FIXME: to be tracked. */ 2.191 + fprintf(stderr, "cannot map mfn page %lx gpfn %lx: %s\n", 2.192 + xc_ia64_p2m_mfn(&p2m_table, N), 2.193 + N, safe_strerror(errno)); 2.194 + continue; 2.195 + } 2.196 2.197 - if (write(io_fd, mem, PAGE_SIZE) != PAGE_SIZE) { 2.198 - ERROR("Error when writing to state file (5)"); 2.199 + if (!write_exact(io_fd, &N, sizeof(N))) { 2.200 + ERROR("write: p2m_size"); 2.201 + munmap(mem, PAGE_SIZE); 2.202 + goto out; 2.203 + } 2.204 + 2.205 + if (write(io_fd, mem, PAGE_SIZE) != PAGE_SIZE) { 2.206 + ERROR("Error when writing to state file (5)"); 2.207 + munmap(mem, PAGE_SIZE); 2.208 + goto out; 2.209 + } 2.210 munmap(mem, PAGE_SIZE); 2.211 - goto out; 2.212 + sent_this_iter++; 2.213 + total_sent++; 2.214 } 2.215 - munmap(mem, PAGE_SIZE); 2.216 - sent_this_iter++; 2.217 - total_sent++; 2.218 } 2.219 2.220 if (last_iter) 2.221 @@ -420,36 +473,69 @@ xc_domain_save(int xc_handle, int io_fd, 2.222 } 2.223 } 2.224 2.225 - /* Send through a list of all the PFNs that were not in map at the close */ 2.226 + /* 2.227 + * Send through a list of all the PFNs that were not in map at the close. 2.228 + * We send pages which was allocated. However balloon driver may 2.229 + * decreased after sending page. So we have to check the freed 2.230 + * page after pausing the domain. 2.231 + */ 2.232 { 2.233 - unsigned int i,j; 2.234 + unsigned long N; 2.235 unsigned long pfntab[1024]; 2.236 + unsigned int j; 2.237 2.238 - for (i = 0, j = 0; i < p2m_size; i++) { 2.239 - if (page_array[i] == INVALID_MFN) 2.240 - j++; 2.241 + j = 0; 2.242 + for (p = memmap_desc_start; 2.243 + p < memmap_desc_end; 2.244 + p += memmap_info->efi_memdesc_size) { 2.245 + md = p; 2.246 + if (md->type != EFI_CONVENTIONAL_MEMORY || 2.247 + md->attribute != EFI_MEMORY_WB || 2.248 + md->num_pages == 0) 2.249 + continue; 2.250 + for (N = md->phys_addr >> PAGE_SHIFT; 2.251 + N < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> 2.252 + PAGE_SHIFT; 2.253 + N++) { 2.254 + if (!xc_ia64_p2m_allocated(&p2m_table, N)) 2.255 + j++; 2.256 + } 2.257 } 2.258 - 2.259 if (!write_exact(io_fd, &j, sizeof(unsigned int))) { 2.260 ERROR("Error when writing to state file (6a)"); 2.261 goto out; 2.262 } 2.263 - 2.264 - for (i = 0, j = 0; i < p2m_size; ) { 2.265 - 2.266 - if (page_array[i] == INVALID_MFN) 2.267 - pfntab[j++] = i; 2.268 - 2.269 - i++; 2.270 - if (j == 1024 || i == p2m_size) { 2.271 - if (!write_exact(io_fd, &pfntab, sizeof(unsigned long)*j)) { 2.272 - ERROR("Error when writing to state file (6b)"); 2.273 - goto out; 2.274 + 2.275 + j = 0; 2.276 + for (p = memmap_desc_start; 2.277 + p < memmap_desc_end; 2.278 + p += memmap_info->efi_memdesc_size) { 2.279 + md = p; 2.280 + if (md->type != EFI_CONVENTIONAL_MEMORY || 2.281 + md->attribute != EFI_MEMORY_WB || 2.282 + md->num_pages == 0) 2.283 + continue; 2.284 + for (N = md->phys_addr >> PAGE_SHIFT; 2.285 + N < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> 2.286 + PAGE_SHIFT; 2.287 + N++) { 2.288 + if (!xc_ia64_p2m_allocated(&p2m_table, N)) 2.289 + pfntab[j++] = N; 2.290 + if (j == sizeof(pfntab)/sizeof(pfntab[0])) { 2.291 + if (!write_exact(io_fd, &pfntab, sizeof(pfntab[0]) * j)) { 2.292 + ERROR("Error when writing to state file (6b)"); 2.293 + goto out; 2.294 + } 2.295 + j = 0; 2.296 } 2.297 - j = 0; 2.298 } 2.299 } 2.300 - 2.301 + if (j > 0) { 2.302 + if (!write_exact(io_fd, &pfntab, sizeof(pfntab[0]) * j)) { 2.303 + ERROR("Error when writing to state file (6b)"); 2.304 + goto out; 2.305 + } 2.306 + } 2.307 } 2.308 2.309 if (xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt)) { 2.310 @@ -494,13 +580,17 @@ xc_domain_save(int xc_handle, int io_fd, 2.311 } 2.312 } 2.313 2.314 - free(page_array); 2.315 unlock_pages(to_send, bitmap_size); 2.316 free(to_send); 2.317 unlock_pages(to_skip, bitmap_size); 2.318 free(to_skip); 2.319 if (live_shinfo) 2.320 munmap(live_shinfo, PAGE_SIZE); 2.321 + if (memmap_info_live) 2.322 + munmap(memmap_info_live, memmap_size); 2.323 + if (memmap_info) 2.324 + free(memmap_info); 2.325 + xc_ia64_p2m_unmap(&p2m_table); 2.326 2.327 fprintf(stderr,"Save exit rc=%d\n",rc); 2.328
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/libxc/ia64/xc_ia64_save_restore.h Thu Sep 06 15:36:13 2007 -0600 3.3 @@ -0,0 +1,44 @@ 3.4 +/****************************************************************************** 3.5 + * xc_ia64_save_restore.h 3.6 + * 3.7 + * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp> 3.8 + * VA Linux Systems Japan K.K. 3.9 + * 3.10 + * This program is free software; you can redistribute it and/or modify 3.11 + * it under the terms of the GNU General Public License as published by 3.12 + * the Free Software Foundation; either version 2 of the License, or 3.13 + * (at your option) any later version. 3.14 + * 3.15 + * This program is distributed in the hope that it will be useful, 3.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 3.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3.18 + * GNU General Public License for more details. 3.19 + * 3.20 + * You should have received a copy of the GNU General Public License 3.21 + * along with this program; if not, write to the Free Software 3.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 3.23 + * 3.24 + */ 3.25 + 3.26 +#ifndef XC_IA64_SAVE_RESTORE_H 3.27 +#define XC_IA64_SR_H 3.28 + 3.29 + /* introduced changeset 10692:306d7857928c of xen-ia64-unstable.ht */ 3.30 +#define XC_IA64_SR_FORMAT_VER_ONE 1UL 3.31 + /* using foreign p2m exposure version */ 3.32 +#define XC_IA64_SR_FORMAT_VER_TWO 2UL 3.33 +#define XC_IA64_SR_FORMAT_VER_MAX 2UL 3.34 + 3.35 +#define XC_IA64_SR_FORMAT_VER_CURRENT XC_IA64_SR_FORMAT_VER_TWO 3.36 + 3.37 +#endif /* XC_IA64_SAVE_RESTORE_H */ 3.38 + 3.39 +/* 3.40 + * Local variables: 3.41 + * mode: C 3.42 + * c-set-style: "BSD" 3.43 + * c-basic-offset: 4 3.44 + * tab-width: 4 3.45 + * indent-tabs-mode: nil 3.46 + * End: 3.47 + */