direct-io.hg
changeset 6737:413c911e5780
Re-indent xc_linux_restore, and add code to force PAE
root pgdirs below 4GB on restore.
Signed-off-by: Ian Pratt <ian@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
root pgdirs below 4GB on restore.
Signed-off-by: Ian Pratt <ian@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Mon Sep 12 12:48:33 2005 +0000 (2005-09-12) |
parents | f752e0c873a6 |
children | 7ae8090e5f67 |
files | tools/libxc/xc_linux_restore.c |
line diff
1.1 --- a/tools/libxc/xc_linux_restore.c Mon Sep 12 12:32:20 2005 +0000 1.2 +++ b/tools/libxc/xc_linux_restore.c Mon Sep 12 12:48:33 2005 +0000 1.3 @@ -42,18 +42,18 @@ read_exact(int fd, void *buf, size_t cou 1.4 unsigned char *b = buf; 1.5 1.6 while (r < count) { 1.7 - s = read(fd, &b[r], count - r); 1.8 - if (s <= 0) 1.9 - break; 1.10 - r += s; 1.11 + s = read(fd, &b[r], count - r); 1.12 + if (s <= 0) 1.13 + break; 1.14 + r += s; 1.15 } 1.16 1.17 return r; 1.18 } 1.19 1.20 int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, 1.21 - unsigned int store_evtchn, unsigned long *store_mfn, 1.22 - unsigned int console_evtchn, unsigned long *console_mfn) 1.23 + unsigned int store_evtchn, unsigned long *store_mfn, 1.24 + unsigned int console_evtchn, unsigned long *console_mfn) 1.25 { 1.26 dom0_op_t op; 1.27 int rc = 1, i, n, k; 1.28 @@ -91,6 +91,8 @@ int xc_linux_restore(int xc_handle, int 1.29 /* A temporary mapping of the guest's start_info page. */ 1.30 start_info_t *start_info; 1.31 1.32 + int pt_levels = 2; /* XXX auto-detect this */ 1.33 + 1.34 char *region_base; 1.35 1.36 xc_mmu_t *mmu = NULL; 1.37 @@ -112,8 +114,8 @@ int xc_linux_restore(int xc_handle, int 1.38 } 1.39 1.40 if (read_exact(io_fd, pfn_to_mfn_frame_list, PAGE_SIZE) != PAGE_SIZE) { 1.41 - ERR("read pfn_to_mfn_frame_list failed"); 1.42 - goto out; 1.43 + ERR("read pfn_to_mfn_frame_list failed"); 1.44 + goto out; 1.45 } 1.46 1.47 /* We want zeroed memory so use calloc rather than malloc. */ 1.48 @@ -289,10 +291,10 @@ int xc_linux_restore(int xc_handle, int 1.49 if ( xpfn >= nr_pfns ) 1.50 { 1.51 ERR("Frame number in type %lu page " 1.52 - "table is out of range. i=%d k=%d " 1.53 - "pfn=0x%lx nr_pfns=%lu", 1.54 - region_pfn_type[i]>>28, i, 1.55 - k, xpfn, nr_pfns); 1.56 + "table is out of range. i=%d k=%d " 1.57 + "pfn=0x%lx nr_pfns=%lu", 1.58 + region_pfn_type[i]>>28, i, 1.59 + k, xpfn, nr_pfns); 1.60 goto out; 1.61 } 1.62 1.63 @@ -317,10 +319,10 @@ int xc_linux_restore(int xc_handle, int 1.64 if ( xpfn >= nr_pfns ) 1.65 { 1.66 ERR("Frame number in type %lu page" 1.67 - " table is out of range. i=%d k=%d " 1.68 - "pfn=%lu nr_pfns=%lu", 1.69 - region_pfn_type[i]>>28, i, k, 1.70 - xpfn, nr_pfns); 1.71 + " table is out of range. i=%d k=%d " 1.72 + "pfn=%lu nr_pfns=%lu", 1.73 + region_pfn_type[i]>>28, i, k, 1.74 + xpfn, nr_pfns); 1.75 goto out; 1.76 } 1.77 1.78 @@ -334,8 +336,8 @@ int xc_linux_restore(int xc_handle, int 1.79 1.80 default: 1.81 ERR("Bogus page type %lx page table is " 1.82 - "out of range. i=%d nr_pfns=%lu", 1.83 - region_pfn_type[i], i, nr_pfns); 1.84 + "out of range. i=%d nr_pfns=%lu", 1.85 + region_pfn_type[i], i, nr_pfns); 1.86 goto out; 1.87 1.88 } /* end of page type switch statement */ 1.89 @@ -362,8 +364,8 @@ int xc_linux_restore(int xc_handle, int 1.90 } 1.91 1.92 if ( xc_add_mmu_update(xc_handle, mmu, 1.93 - (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, 1.94 - pfn) ) 1.95 + (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, 1.96 + pfn) ) 1.97 { 1.98 printf("machpys mfn=%ld pfn=%ld\n",mfn,pfn); 1.99 goto out; 1.100 @@ -377,6 +379,33 @@ int xc_linux_restore(int xc_handle, int 1.101 1.102 DPRINTF("Received all pages\n"); 1.103 1.104 + if ( pt_levels == 3 ) 1.105 + { 1.106 + /* Get all PGDs below 4GB. */ 1.107 + for ( i = 0; i < nr_pfns; i++ ) 1.108 + { 1.109 + if ( ((pfn_type[i] & LTABTYPE_MASK) == L3TAB) && 1.110 + (pfn_to_mfn_table[i] > 0xfffffUL) ) 1.111 + { 1.112 + unsigned long new_mfn = xc_make_page_below_4G( 1.113 + xc_handle, dom, pfn_to_mfn_table[i]); 1.114 + if ( new_mfn == 0 ) 1.115 + { 1.116 + fprintf(stderr, "Couldn't get a page below 4GB :-(\n"); 1.117 + goto out; 1.118 + } 1.119 + pfn_to_mfn_table[i] = new_mfn; 1.120 + if ( xc_add_mmu_update( 1.121 + xc_handle, mmu, (new_mfn << PAGE_SHIFT) | 1.122 + MMU_MACHPHYS_UPDATE, i) ) 1.123 + { 1.124 + fprintf(stderr, "Couldn't m2p on PAE root pgdir\n"); 1.125 + goto out; 1.126 + } 1.127 + } 1.128 + } 1.129 + } 1.130 + 1.131 if ( xc_finish_mmu_updates(xc_handle, mmu) ) 1.132 goto out; 1.133 1.134 @@ -410,57 +439,57 @@ int xc_linux_restore(int xc_handle, int 1.135 1.136 /* Get the list of PFNs that are not in the psuedo-phys map */ 1.137 { 1.138 - unsigned int count; 1.139 + unsigned int count; 1.140 unsigned long *pfntab; 1.141 - int rc; 1.142 + int rc; 1.143 1.144 - if ( read_exact(io_fd, &count, sizeof(count)) != sizeof(count) ) 1.145 - { 1.146 - ERR("Error when reading pfn count"); 1.147 - goto out; 1.148 - } 1.149 + if ( read_exact(io_fd, &count, sizeof(count)) != sizeof(count) ) 1.150 + { 1.151 + ERR("Error when reading pfn count"); 1.152 + goto out; 1.153 + } 1.154 1.155 - pfntab = malloc( sizeof(unsigned int) * count ); 1.156 - if ( pfntab == NULL ) 1.157 - { 1.158 - ERR("Out of memory"); 1.159 - goto out; 1.160 - } 1.161 + pfntab = malloc( sizeof(unsigned int) * count ); 1.162 + if ( pfntab == NULL ) 1.163 + { 1.164 + ERR("Out of memory"); 1.165 + goto out; 1.166 + } 1.167 1.168 - if ( read_exact(io_fd, pfntab, sizeof(unsigned int)*count) != 1.169 + if ( read_exact(io_fd, pfntab, sizeof(unsigned int)*count) != 1.170 sizeof(unsigned int)*count ) 1.171 - { 1.172 - ERR("Error when reading pfntab"); 1.173 - goto out; 1.174 - } 1.175 + { 1.176 + ERR("Error when reading pfntab"); 1.177 + goto out; 1.178 + } 1.179 1.180 - for ( i = 0; i < count; i++ ) 1.181 - { 1.182 - unsigned long pfn = pfntab[i]; 1.183 - pfntab[i]=pfn_to_mfn_table[pfn]; 1.184 - pfn_to_mfn_table[pfn] = 0x80000001; // not in pmap 1.185 - } 1.186 + for ( i = 0; i < count; i++ ) 1.187 + { 1.188 + unsigned long pfn = pfntab[i]; 1.189 + pfntab[i]=pfn_to_mfn_table[pfn]; 1.190 + pfn_to_mfn_table[pfn] = 0x80000001; // not in pmap 1.191 + } 1.192 1.193 - if ( count > 0 ) 1.194 - { 1.195 + if ( count > 0 ) 1.196 + { 1.197 struct xen_memory_reservation reservation = { 1.198 .extent_start = pfntab, 1.199 .nr_extents = count, 1.200 .extent_order = 0, 1.201 .domid = dom 1.202 }; 1.203 - if ( (rc = xc_memory_op(xc_handle, 1.204 + if ( (rc = xc_memory_op(xc_handle, 1.205 XENMEM_decrease_reservation, 1.206 &reservation)) != count ) 1.207 - { 1.208 - ERR("Could not decrease reservation : %d",rc); 1.209 - goto out; 1.210 - } 1.211 - else 1.212 - { 1.213 - printf("Decreased reservation by %d pages\n", count); 1.214 - } 1.215 - } 1.216 + { 1.217 + ERR("Could not decrease reservation : %d",rc); 1.218 + goto out; 1.219 + } 1.220 + else 1.221 + { 1.222 + printf("Decreased reservation by %d pages\n", count); 1.223 + } 1.224 + } 1.225 } 1.226 1.227 if ( read_exact(io_fd, &ctxt, sizeof(ctxt)) != sizeof(ctxt) || 1.228 @@ -484,10 +513,10 @@ int xc_linux_restore(int xc_handle, int 1.229 start_info->shared_info = shared_info_frame << PAGE_SHIFT; 1.230 start_info->flags = 0; 1.231 *store_mfn = start_info->store_mfn = 1.232 - pfn_to_mfn_table[start_info->store_mfn]; 1.233 + pfn_to_mfn_table[start_info->store_mfn]; 1.234 start_info->store_evtchn = store_evtchn; 1.235 *console_mfn = start_info->console_mfn = 1.236 - pfn_to_mfn_table[start_info->console_mfn]; 1.237 + pfn_to_mfn_table[start_info->console_mfn]; 1.238 start_info->console_evtchn = console_evtchn; 1.239 munmap(start_info, PAGE_SIZE); 1.240 1.241 @@ -522,7 +551,7 @@ int xc_linux_restore(int xc_handle, int 1.242 1.243 /* clear any pending events and the selector */ 1.244 memset(&(shared_info->evtchn_pending[0]), 0, 1.245 - sizeof (shared_info->evtchn_pending)); 1.246 + sizeof (shared_info->evtchn_pending)); 1.247 for ( i = 0; i < MAX_VIRT_CPUS; i++ ) 1.248 shared_info->vcpu_data[i].evtchn_pending_sel = 0; 1.249 1.250 @@ -548,7 +577,7 @@ int xc_linux_restore(int xc_handle, int 1.251 } 1.252 1.253 if ( (live_pfn_to_mfn_table = 1.254 - xc_map_foreign_batch(xc_handle, dom, 1.255 + xc_map_foreign_batch(xc_handle, dom, 1.256 PROT_WRITE, 1.257 pfn_to_mfn_frame_list, 1.258 (nr_pfns+1023)/1024 )) == 0 )