ia64/xen-unstable
changeset 13968:0d488e53446a
Remove old elf-parsing code from tools and from Xen.
Signed-off-by: Keir Fraser <keir@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kfraser@localhost.localdomain |
---|---|
date | Thu Feb 15 10:25:39 2007 +0000 (2007-02-15) |
parents | 82f66bc01da2 |
children | 047b3e9f9032 |
files | tools/libxc/Makefile tools/libxc/xc_linux_build.c tools/libxc/xc_load_bin.c tools/libxc/xc_load_elf.c tools/libxc/xc_private.c tools/libxc/xg_private.h xen/common/elf.c |
line diff
1.1 --- a/tools/libxc/Makefile Wed Feb 14 12:18:32 2007 -0800 1.2 +++ b/tools/libxc/Makefile Thu Feb 15 10:25:39 2007 +0000 1.3 @@ -22,11 +22,7 @@ CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris. 1.4 CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c 1.5 1.6 GUEST_SRCS-y := 1.7 -GUEST_SRCS-y += xc_load_bin.c 1.8 -GUEST_SRCS-y += xc_load_elf.c 1.9 GUEST_SRCS-y += xg_private.c 1.10 -#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c 1.11 -#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c 1.12 GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c 1.13 GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c xc_hvm_restore.c xc_hvm_save.c 1.14
2.1 --- a/tools/libxc/xc_linux_build.c Wed Feb 14 12:18:32 2007 -0800 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,1319 +0,0 @@ 2.4 -/****************************************************************************** 2.5 - * xc_linux_build.c 2.6 - */ 2.7 - 2.8 -#include <stddef.h> 2.9 -#include "xg_private.h" 2.10 -#include "xc_private.h" 2.11 -#include <xenctrl.h> 2.12 - 2.13 -#include "xc_elf.h" 2.14 -#include <stdlib.h> 2.15 -#include <unistd.h> 2.16 -#include <inttypes.h> 2.17 -#include <zlib.h> 2.18 - 2.19 -/* Handy for printing out '0' prepended values at native pointer size */ 2.20 -#define _p(a) ((void *) ((ulong)a)) 2.21 - 2.22 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) 2.23 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) 2.24 -#if defined(__i386__) 2.25 -#define L3_PROT (_PAGE_PRESENT) 2.26 -#elif defined(__x86_64__) 2.27 -#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) 2.28 -#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) 2.29 -#endif 2.30 - 2.31 -#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) 2.32 -#define round_pgdown(_p) ((_p)&PAGE_MASK) 2.33 - 2.34 -struct initrd_info { 2.35 - enum { INITRD_none, INITRD_file, INITRD_mem } type; 2.36 - /* 2.37 - * .len must be filled in by the user for type==INITRD_mem. It is 2.38 - * filled in by load_initrd() for INITRD_file and unused for 2.39 - * INITRD_none. 2.40 - */ 2.41 - unsigned long len; 2.42 - union { 2.43 - gzFile file_handle; 2.44 - char *mem_addr; 2.45 - } u; 2.46 -}; 2.47 - 2.48 -static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = { 2.49 - [XENFEAT_writable_page_tables] = "writable_page_tables", 2.50 - [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables", 2.51 - [XENFEAT_auto_translated_physmap] = "auto_translated_physmap", 2.52 - [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel", 2.53 - [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb" 2.54 -}; 2.55 - 2.56 -static inline void set_feature_bit (int nr, uint32_t *addr) 2.57 -{ 2.58 - addr[nr>>5] |= (1<<(nr&31)); 2.59 -} 2.60 - 2.61 -static inline int test_feature_bit(int nr, uint32_t *addr) 2.62 -{ 2.63 - return !!(addr[nr>>5] & (1<<(nr&31))); 2.64 -} 2.65 - 2.66 -static int parse_features( 2.67 - const char *feats, 2.68 - uint32_t supported[XENFEAT_NR_SUBMAPS], 2.69 - uint32_t required[XENFEAT_NR_SUBMAPS]) 2.70 -{ 2.71 - const char *end, *p; 2.72 - int i, req; 2.73 - 2.74 - if ( (end = strchr(feats, ',')) == NULL ) 2.75 - end = feats + strlen(feats); 2.76 - 2.77 - while ( feats < end ) 2.78 - { 2.79 - p = strchr(feats, '|'); 2.80 - if ( (p == NULL) || (p > end) ) 2.81 - p = end; 2.82 - 2.83 - req = (*feats == '!'); 2.84 - if ( req ) 2.85 - feats++; 2.86 - 2.87 - for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ ) 2.88 - { 2.89 - if ( feature_names[i] == NULL ) 2.90 - continue; 2.91 - 2.92 - if ( strncmp(feature_names[i], feats, p-feats) == 0 ) 2.93 - { 2.94 - set_feature_bit(i, supported); 2.95 - if ( required && req ) 2.96 - set_feature_bit(i, required); 2.97 - break; 2.98 - } 2.99 - } 2.100 - 2.101 - if ( i == XENFEAT_NR_SUBMAPS*32 ) 2.102 - { 2.103 - ERROR("Unknown feature \"%.*s\".", (int)(p-feats), feats); 2.104 - if ( req ) 2.105 - { 2.106 - ERROR("Kernel requires an unknown hypervisor feature."); 2.107 - return -EINVAL; 2.108 - } 2.109 - } 2.110 - 2.111 - feats = p; 2.112 - if ( *feats == '|' ) 2.113 - feats++; 2.114 - } 2.115 - 2.116 - return -EINVAL; 2.117 -} 2.118 - 2.119 -static int probeimageformat(const char *image, 2.120 - unsigned long image_size, 2.121 - struct load_funcs *load_funcs) 2.122 -{ 2.123 - if ( probe_elf(image, image_size, load_funcs) && 2.124 - probe_bin(image, image_size, load_funcs) ) 2.125 - { 2.126 - xc_set_error(XC_INVALID_KERNEL, "Not a valid ELF or raw kernel image"); 2.127 - return -EINVAL; 2.128 - } 2.129 - 2.130 - return 0; 2.131 -} 2.132 - 2.133 -static int load_initrd(int xc_handle, domid_t dom, 2.134 - struct initrd_info *initrd, 2.135 - unsigned long physbase, 2.136 - xen_pfn_t *phys_to_mach) 2.137 -{ 2.138 - char page[PAGE_SIZE]; 2.139 - unsigned long pfn_start, pfn; 2.140 - 2.141 - if ( initrd->type == INITRD_none ) 2.142 - return 0; 2.143 - 2.144 - pfn_start = physbase >> PAGE_SHIFT; 2.145 - 2.146 - if ( initrd->type == INITRD_mem ) 2.147 - { 2.148 - unsigned long nr_pages = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT; 2.149 - 2.150 - for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ ) 2.151 - { 2.152 - xc_copy_to_domain_page( 2.153 - xc_handle, dom, phys_to_mach[pfn], 2.154 - &initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]); 2.155 - } 2.156 - } 2.157 - else 2.158 - { 2.159 - int readlen; 2.160 - 2.161 - pfn = pfn_start; 2.162 - initrd->len = 0; 2.163 - 2.164 - /* gzread returns 0 on EOF */ 2.165 - while ( (readlen = gzread(initrd->u.file_handle, page, PAGE_SIZE)) ) 2.166 - { 2.167 - if ( readlen < 0 ) 2.168 - { 2.169 - PERROR("Error reading initrd image, could not"); 2.170 - return -EINVAL; 2.171 - } 2.172 - 2.173 - initrd->len += readlen; 2.174 - xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn++], page); 2.175 - } 2.176 - } 2.177 - 2.178 - return 0; 2.179 -} 2.180 - 2.181 -#define alloc_pt(ltab, vltab) \ 2.182 -do { \ 2.183 - ltab = ppt_alloc++; \ 2.184 - ltab = (uint64_t)page_array[ltab] << PAGE_SHIFT; \ 2.185 - if ( vltab != NULL ) \ 2.186 - munmap(vltab, PAGE_SIZE); \ 2.187 - if ( (vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, \ 2.188 - PROT_READ|PROT_WRITE, \ 2.189 - ltab >> PAGE_SHIFT)) == NULL ) \ 2.190 - goto error_out; \ 2.191 - memset(vltab, 0x0, PAGE_SIZE); \ 2.192 -} while ( 0 ) 2.193 - 2.194 -#if defined(__i386__) 2.195 - 2.196 -static int setup_pg_tables(int xc_handle, uint32_t dom, 2.197 - vcpu_guest_context_t *ctxt, 2.198 - unsigned long dsi_v_start, 2.199 - unsigned long v_end, 2.200 - xen_pfn_t *page_array, 2.201 - unsigned long vpt_start, 2.202 - unsigned long vpt_end, 2.203 - unsigned shadow_mode_enabled) 2.204 -{ 2.205 - l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; 2.206 - l2_pgentry_t *vl2tab=NULL, *vl2e=NULL; 2.207 - unsigned long l1tab = 0; 2.208 - unsigned long l2tab = 0; 2.209 - unsigned long ppt_alloc; 2.210 - unsigned long count; 2.211 - 2.212 - ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT; 2.213 - alloc_pt(l2tab, vl2tab); 2.214 - vl2e = &vl2tab[l2_table_offset(dsi_v_start)]; 2.215 - ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT); 2.216 - 2.217 - for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ ) 2.218 - { 2.219 - if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) 2.220 - { 2.221 - alloc_pt(l1tab, vl1tab); 2.222 - vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))]; 2.223 - *vl2e++ = l1tab | L2_PROT; 2.224 - } 2.225 - 2.226 - *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT; 2.227 - 2.228 - if ( !shadow_mode_enabled ) 2.229 - if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) && 2.230 - (count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) ) 2.231 - *vl1e &= ~_PAGE_RW; 2.232 - 2.233 - vl1e++; 2.234 - } 2.235 - munmap(vl1tab, PAGE_SIZE); 2.236 - munmap(vl2tab, PAGE_SIZE); 2.237 - return 0; 2.238 - 2.239 - error_out: 2.240 - if (vl1tab) 2.241 - munmap(vl1tab, PAGE_SIZE); 2.242 - if (vl2tab) 2.243 - munmap(vl2tab, PAGE_SIZE); 2.244 - return -1; 2.245 -} 2.246 - 2.247 -static int setup_pg_tables_pae(int xc_handle, uint32_t dom, 2.248 - vcpu_guest_context_t *ctxt, 2.249 - unsigned long dsi_v_start, 2.250 - unsigned long v_end, 2.251 - xen_pfn_t *page_array, 2.252 - unsigned long vpt_start, 2.253 - unsigned long vpt_end, 2.254 - unsigned shadow_mode_enabled, 2.255 - unsigned pae_mode) 2.256 -{ 2.257 - l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL; 2.258 - l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL; 2.259 - l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL; 2.260 - uint64_t l1tab, l2tab, l3tab; 2.261 - unsigned long ppt_alloc, count, nmfn; 2.262 - 2.263 - /* First allocate page for page dir. */ 2.264 - ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT; 2.265 - 2.266 - if ( pae_mode == PAEKERN_extended_cr3 ) 2.267 - { 2.268 - ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3); 2.269 - } 2.270 - else if ( page_array[ppt_alloc] > 0xfffff ) 2.271 - { 2.272 - nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]); 2.273 - if ( nmfn == 0 ) 2.274 - { 2.275 - DPRINTF("Couldn't get a page below 4GB :-(\n"); 2.276 - goto error_out; 2.277 - } 2.278 - page_array[ppt_alloc] = nmfn; 2.279 - } 2.280 - 2.281 - alloc_pt(l3tab, vl3tab); 2.282 - vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)]; 2.283 - ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT); 2.284 - 2.285 - for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++) 2.286 - { 2.287 - if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) ) 2.288 - { 2.289 - if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) ) 2.290 - { 2.291 - alloc_pt(l2tab, vl2tab); 2.292 - vl2e = &vl2tab[l2_table_offset_pae( 2.293 - dsi_v_start + (count << PAGE_SHIFT))]; 2.294 - *vl3e++ = l2tab | L3_PROT; 2.295 - } 2.296 - 2.297 - alloc_pt(l1tab, vl1tab); 2.298 - vl1e = &vl1tab[l1_table_offset_pae( 2.299 - dsi_v_start + (count << PAGE_SHIFT))]; 2.300 - *vl2e++ = l1tab | L2_PROT; 2.301 - 2.302 - } 2.303 - 2.304 - *vl1e = ((uint64_t)page_array[count] << PAGE_SHIFT) | L1_PROT; 2.305 - 2.306 - if ( !shadow_mode_enabled ) 2.307 - if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) && 2.308 - (count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) ) 2.309 - *vl1e &= ~_PAGE_RW; 2.310 - 2.311 - vl1e++; 2.312 - } 2.313 - 2.314 - /* Xen requires a mid-level pgdir mapping 0xC0000000 region. */ 2.315 - if ( (vl3tab[3] & _PAGE_PRESENT) == 0 ) 2.316 - { 2.317 - alloc_pt(l2tab, vl2tab); 2.318 - vl3tab[3] = l2tab | L3_PROT; 2.319 - } 2.320 - 2.321 - munmap(vl1tab, PAGE_SIZE); 2.322 - munmap(vl2tab, PAGE_SIZE); 2.323 - munmap(vl3tab, PAGE_SIZE); 2.324 - return 0; 2.325 - 2.326 - error_out: 2.327 - if (vl1tab) 2.328 - munmap(vl1tab, PAGE_SIZE); 2.329 - if (vl2tab) 2.330 - munmap(vl2tab, PAGE_SIZE); 2.331 - if (vl3tab) 2.332 - munmap(vl3tab, PAGE_SIZE); 2.333 - return -1; 2.334 -} 2.335 - 2.336 -#endif 2.337 - 2.338 -#if defined(__x86_64__) 2.339 - 2.340 -static int setup_pg_tables_64(int xc_handle, uint32_t dom, 2.341 - vcpu_guest_context_t *ctxt, 2.342 - unsigned long dsi_v_start, 2.343 - unsigned long v_end, 2.344 - xen_pfn_t *page_array, 2.345 - unsigned long vpt_start, 2.346 - unsigned long vpt_end, 2.347 - int shadow_mode_enabled) 2.348 -{ 2.349 - l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; 2.350 - l2_pgentry_t *vl2tab=NULL, *vl2e=NULL; 2.351 - l3_pgentry_t *vl3tab=NULL, *vl3e=NULL; 2.352 - l4_pgentry_t *vl4tab=NULL, *vl4e=NULL; 2.353 - unsigned long l2tab = 0; 2.354 - unsigned long l1tab = 0; 2.355 - unsigned long l3tab = 0; 2.356 - unsigned long l4tab = 0; 2.357 - unsigned long ppt_alloc; 2.358 - unsigned long count; 2.359 - 2.360 - /* First allocate page for page dir. */ 2.361 - ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT; 2.362 - alloc_pt(l4tab, vl4tab); 2.363 - vl4e = &vl4tab[l4_table_offset(dsi_v_start)]; 2.364 - ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT); 2.365 - 2.366 - for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++) 2.367 - { 2.368 - if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) ) 2.369 - { 2.370 - alloc_pt(l1tab, vl1tab); 2.371 - 2.372 - if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) ) 2.373 - { 2.374 - alloc_pt(l2tab, vl2tab); 2.375 - if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) ) 2.376 - { 2.377 - alloc_pt(l3tab, vl3tab); 2.378 - vl3e = &vl3tab[l3_table_offset(dsi_v_start + (count<<PAGE_SHIFT))]; 2.379 - *vl4e++ = l3tab | L4_PROT; 2.380 - } 2.381 - vl2e = &vl2tab[l2_table_offset(dsi_v_start + (count<<PAGE_SHIFT))]; 2.382 - *vl3e++ = l2tab | L3_PROT; 2.383 - } 2.384 - vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))]; 2.385 - *vl2e++ = l1tab | L2_PROT; 2.386 - } 2.387 - 2.388 - *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT; 2.389 - 2.390 - if ( !shadow_mode_enabled ) 2.391 - if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) && 2.392 - (count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) ) 2.393 - *vl1e &= ~_PAGE_RW; 2.394 - 2.395 - vl1e++; 2.396 - } 2.397 - 2.398 - munmap(vl1tab, PAGE_SIZE); 2.399 - munmap(vl2tab, PAGE_SIZE); 2.400 - munmap(vl3tab, PAGE_SIZE); 2.401 - munmap(vl4tab, PAGE_SIZE); 2.402 - return 0; 2.403 - 2.404 - error_out: 2.405 - if (vl1tab) 2.406 - munmap(vl1tab, PAGE_SIZE); 2.407 - if (vl2tab) 2.408 - munmap(vl2tab, PAGE_SIZE); 2.409 - if (vl3tab) 2.410 - munmap(vl3tab, PAGE_SIZE); 2.411 - if (vl4tab) 2.412 - munmap(vl4tab, PAGE_SIZE); 2.413 - return -1; 2.414 -} 2.415 -#endif 2.416 - 2.417 -#ifdef __ia64__ 2.418 -static int setup_guest(int xc_handle, 2.419 - uint32_t dom, 2.420 - const char *image, unsigned long image_size, 2.421 - struct initrd_info *initrd, 2.422 - unsigned long nr_pages, 2.423 - unsigned long *pvsi, unsigned long *pvke, 2.424 - unsigned long *pvss, vcpu_guest_context_t *ctxt, 2.425 - const char *cmdline, 2.426 - unsigned long shared_info_frame, 2.427 - unsigned long flags, 2.428 - unsigned int store_evtchn, unsigned long *store_mfn, 2.429 - unsigned int console_evtchn, unsigned long *console_mfn, 2.430 - uint32_t required_features[XENFEAT_NR_SUBMAPS]) 2.431 -{ 2.432 - xen_pfn_t *page_array = NULL; 2.433 - struct load_funcs load_funcs; 2.434 - struct domain_setup_info dsi; 2.435 - unsigned long vinitrd_start; 2.436 - unsigned long vinitrd_end; 2.437 - unsigned long v_end; 2.438 - unsigned long start_page, pgnr; 2.439 - start_info_t *start_info; 2.440 - unsigned long start_info_mpa; 2.441 - struct xen_ia64_boot_param *bp; 2.442 - shared_info_t *shared_info; 2.443 - int i; 2.444 - DECLARE_DOMCTL; 2.445 - int rc; 2.446 - 2.447 - rc = probeimageformat(image, image_size, &load_funcs); 2.448 - if ( rc != 0 ) 2.449 - goto error_out; 2.450 - 2.451 - memset(&dsi, 0, sizeof(struct domain_setup_info)); 2.452 - 2.453 - rc = (load_funcs.parseimage)(image, image_size, &dsi); 2.454 - if ( rc != 0 ) 2.455 - goto error_out; 2.456 - 2.457 - if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL ) 2.458 - { 2.459 - PERROR("Could not allocate memory"); 2.460 - goto error_out; 2.461 - } 2.462 - for ( i = 0; i < nr_pages; i++ ) 2.463 - page_array[i] = i; 2.464 - if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages, 2.465 - 0, 0, page_array) ) 2.466 - { 2.467 - PERROR("Could not allocate memory for PV guest.\n"); 2.468 - goto error_out; 2.469 - } 2.470 - 2.471 - dsi.v_start = round_pgdown(dsi.v_start); 2.472 - vinitrd_start = round_pgup(dsi.v_end); 2.473 - start_info_mpa = (nr_pages - 3) << PAGE_SHIFT; 2.474 - *pvke = dsi.v_kernentry; 2.475 - 2.476 - /* Build firmware. */ 2.477 - memset(&domctl.u.arch_setup, 0, sizeof(domctl.u.arch_setup)); 2.478 - domctl.u.arch_setup.flags = 0; 2.479 - domctl.u.arch_setup.bp = start_info_mpa + sizeof (start_info_t); 2.480 - domctl.u.arch_setup.maxmem = (nr_pages - 3) << PAGE_SHIFT; 2.481 - domctl.cmd = XEN_DOMCTL_arch_setup; 2.482 - domctl.domain = (domid_t)dom; 2.483 - if ( xc_domctl(xc_handle, &domctl) ) 2.484 - goto error_out; 2.485 - 2.486 - start_page = dsi.v_start >> PAGE_SHIFT; 2.487 - /* in order to get initrd->len, we need to load initrd image at first */ 2.488 - if ( load_initrd(xc_handle, dom, initrd, 2.489 - vinitrd_start - dsi.v_start, page_array + start_page) ) 2.490 - goto error_out; 2.491 - 2.492 - vinitrd_end = vinitrd_start + initrd->len; 2.493 - v_end = round_pgup(vinitrd_end); 2.494 - pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT; 2.495 - if ( pgnr > nr_pages ) 2.496 - { 2.497 - PERROR("too small memory is specified. " 2.498 - "At least %ld kb is necessary.\n", 2.499 - pgnr << (PAGE_SHIFT - 10)); 2.500 - } 2.501 - 2.502 - IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" 2.503 - " Loaded kernel: %p->%p\n" 2.504 - " Init. ramdisk: %p->%p\n" 2.505 - " TOTAL: %p->%p\n", 2.506 - _p(dsi.v_kernstart), _p(dsi.v_kernend), 2.507 - _p(vinitrd_start), _p(vinitrd_end), 2.508 - _p(dsi.v_start), _p(v_end)); 2.509 - IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); 2.510 - 2.511 - (load_funcs.loadimage)(image, image_size, xc_handle, dom, 2.512 - page_array + start_page, &dsi); 2.513 - 2.514 - *store_mfn = page_array[nr_pages - 2]; //XXX 2.515 - *console_mfn = page_array[nr_pages - 1]; //XXX 2.516 - IPRINTF("start_info: 0x%lx at 0x%lx, " 2.517 - "store_mfn: 0x%lx at 0x%lx, " 2.518 - "console_mfn: 0x%lx at 0x%lx\n", 2.519 - page_array[nr_pages - 3], nr_pages - 3, 2.520 - *store_mfn, nr_pages - 2, 2.521 - *console_mfn, nr_pages - 1); 2.522 - 2.523 - start_info = xc_map_foreign_range( 2.524 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 2.525 - page_array[nr_pages - 3]); 2.526 - if ( start_info == NULL ) 2.527 - goto error_out; 2.528 - 2.529 - memset(start_info, 0, sizeof(*start_info)); 2.530 - rc = xc_version(xc_handle, XENVER_version, NULL); 2.531 - sprintf(start_info->magic, "xen-%i.%i-ia64", rc >> 16, rc & (0xFFFF)); 2.532 - start_info->flags = flags; 2.533 - start_info->store_mfn = nr_pages - 2; 2.534 - start_info->store_evtchn = store_evtchn; 2.535 - start_info->console.domU.mfn = nr_pages - 1; 2.536 - start_info->console.domU.evtchn = console_evtchn; 2.537 - start_info->nr_pages = nr_pages; // FIXME?: nr_pages - 2 ???? 2.538 - 2.539 - bp = (struct xen_ia64_boot_param *)(start_info + 1); 2.540 - bp->command_line = start_info_mpa + offsetof(start_info_t, cmd_line); 2.541 - if ( cmdline != NULL ) 2.542 - { 2.543 - strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE); 2.544 - start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = 0; 2.545 - } 2.546 - if ( initrd->len != 0 ) 2.547 - { 2.548 - bp->initrd_start = vinitrd_start; 2.549 - bp->initrd_size = initrd->len; 2.550 - } 2.551 - ctxt->user_regs.r28 = start_info_mpa + sizeof (start_info_t); 2.552 - munmap(start_info, PAGE_SIZE); 2.553 - 2.554 - /* 2.555 - * shared_info is assiged into guest pseudo physical address space 2.556 - * by XEN_DOMCTL_arch_setup. shared_info_frame is stale value until that. 2.557 - * So passed shared_info_frame is stale. obtain the right value here. 2.558 - */ 2.559 - domctl.cmd = XEN_DOMCTL_getdomaininfo; 2.560 - domctl.domain = (domid_t)dom; 2.561 - if ( (xc_domctl(xc_handle, &domctl) < 0) || 2.562 - ((uint16_t)domctl.domain != dom) ) 2.563 - { 2.564 - PERROR("Could not get info on domain"); 2.565 - goto error_out; 2.566 - } 2.567 - shared_info_frame = domctl.u.getdomaininfo.shared_info_frame; 2.568 - 2.569 - /* shared_info page starts its life empty. */ 2.570 - shared_info = xc_map_foreign_range( 2.571 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame); 2.572 - printf("shared_info = %p frame=%lx\n", 2.573 - shared_info, shared_info_frame); 2.574 - //memset(shared_info, 0, PAGE_SIZE); 2.575 - /* Mask all upcalls... */ 2.576 - for ( i = 0; i < MAX_VIRT_CPUS; i++ ) 2.577 - shared_info->vcpu_info[i].evtchn_upcall_mask = 1; 2.578 - shared_info->arch.start_info_pfn = nr_pages - 3; 2.579 - 2.580 - munmap(shared_info, PAGE_SIZE); 2.581 - free(page_array); 2.582 - return 0; 2.583 - 2.584 - error_out: 2.585 - free(page_array); 2.586 - return -1; 2.587 -} 2.588 -#else /* x86 */ 2.589 - 2.590 -/* Check if the platform supports the guest kernel format */ 2.591 -static int compat_check(int xc_handle, struct domain_setup_info *dsi) 2.592 -{ 2.593 - xen_capabilities_info_t xen_caps = ""; 2.594 - 2.595 - if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) { 2.596 - xc_set_error(XC_INVALID_KERNEL, 2.597 - "Cannot determine host capabilities."); 2.598 - return 0; 2.599 - } 2.600 - 2.601 -#ifndef __x86_64__//temp 2.602 - if (strstr(xen_caps, "xen-3.0-x86_32p")) { 2.603 - if (dsi->pae_kernel == PAEKERN_bimodal) { 2.604 - dsi->pae_kernel = PAEKERN_extended_cr3; 2.605 - } else if (dsi->pae_kernel == PAEKERN_no) { 2.606 - xc_set_error(XC_INVALID_KERNEL, 2.607 - "Non PAE-kernel on PAE host."); 2.608 - return 0; 2.609 - } 2.610 - } else { 2.611 - if (dsi->pae_kernel == PAEKERN_bimodal) { 2.612 - dsi->pae_kernel = PAEKERN_no; 2.613 - } else if (dsi->pae_kernel != PAEKERN_no) { 2.614 - xc_set_error(XC_INVALID_KERNEL, 2.615 - "PAE-kernel on non-PAE host."); 2.616 - return 0; 2.617 - } 2.618 - } 2.619 -#endif 2.620 - 2.621 - return 1; 2.622 -} 2.623 - 2.624 -static inline int increment_ulong(unsigned long *pval, unsigned long inc) 2.625 -{ 2.626 - if ( inc >= -*pval ) 2.627 - { 2.628 - ERROR("Value wrapped to zero: image too large?"); 2.629 - return 0; 2.630 - } 2.631 - *pval += inc; 2.632 - return 1; 2.633 -} 2.634 - 2.635 -static int setup_guest(int xc_handle, 2.636 - uint32_t dom, 2.637 - const char *image, unsigned long image_size, 2.638 - struct initrd_info *initrd, 2.639 - unsigned long nr_pages, 2.640 - unsigned long *pvsi, unsigned long *pvke, 2.641 - unsigned long *pvss, vcpu_guest_context_t *ctxt, 2.642 - const char *cmdline, 2.643 - unsigned long shared_info_frame, 2.644 - unsigned long flags, 2.645 - unsigned int store_evtchn, unsigned long *store_mfn, 2.646 - unsigned int console_evtchn, unsigned long *console_mfn, 2.647 - uint32_t required_features[XENFEAT_NR_SUBMAPS]) 2.648 -{ 2.649 - xen_pfn_t *page_array = NULL; 2.650 - unsigned long count, i; 2.651 - unsigned long long hypercall_page; 2.652 - int hypercall_page_defined; 2.653 - start_info_t *start_info; 2.654 - shared_info_t *shared_info; 2.655 - const char *p; 2.656 - DECLARE_DOMCTL; 2.657 - int rc; 2.658 - 2.659 - unsigned long nr_pt_pages; 2.660 - unsigned long physmap_pfn; 2.661 - xen_pfn_t *physmap, *physmap_e; 2.662 - 2.663 - struct load_funcs load_funcs; 2.664 - struct domain_setup_info dsi; 2.665 - unsigned long vinitrd_start; 2.666 - unsigned long vphysmap_start; 2.667 - unsigned long vstartinfo_start; 2.668 - unsigned long vstoreinfo_start; 2.669 - unsigned long vconsole_start; 2.670 - unsigned long vsharedinfo_start = 0; /* XXX gcc */ 2.671 - unsigned long vstack_start; 2.672 - unsigned long vstack_end; 2.673 - unsigned long vpt_start; 2.674 - unsigned long vpt_end; 2.675 - unsigned long v_end; 2.676 - unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn; 2.677 - unsigned long shadow_mode_enabled; 2.678 - uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, }; 2.679 - 2.680 - rc = probeimageformat(image, image_size, &load_funcs); 2.681 - if ( rc != 0 ) 2.682 - goto error_out; 2.683 - 2.684 - memset(&dsi, 0, sizeof(struct domain_setup_info)); 2.685 - 2.686 - rc = (load_funcs.parseimage)(image, image_size, &dsi); 2.687 - if ( rc != 0 ) 2.688 - goto error_out; 2.689 - 2.690 - if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 ) 2.691 - { 2.692 - PERROR("Guest OS must load to a page boundary."); 2.693 - goto error_out; 2.694 - } 2.695 - 2.696 - if ( !compat_check(xc_handle, &dsi) ) 2.697 - goto error_out; 2.698 - 2.699 - /* Parse and validate kernel features. */ 2.700 - if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL ) 2.701 - { 2.702 - if ( !parse_features(p, supported_features, required_features) ) 2.703 - { 2.704 - ERROR("Failed to parse guest kernel features."); 2.705 - goto error_out; 2.706 - } 2.707 - 2.708 - IPRINTF("Supported features = { %08x }.\n", supported_features[0]); 2.709 - IPRINTF("Required features = { %08x }.\n", required_features[0]); 2.710 - } 2.711 - 2.712 - for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ ) 2.713 - { 2.714 - if ( (supported_features[i] & required_features[i]) != 2.715 - required_features[i] ) 2.716 - { 2.717 - ERROR("Guest kernel does not support a required feature."); 2.718 - goto error_out; 2.719 - } 2.720 - } 2.721 - 2.722 - shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap, 2.723 - required_features); 2.724 - 2.725 - if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ) 2.726 - { 2.727 - PERROR("Could not allocate memory"); 2.728 - goto error_out; 2.729 - } 2.730 - 2.731 - for ( i = 0; i < nr_pages; i++ ) 2.732 - page_array[i] = i; 2.733 - 2.734 - if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages, 2.735 - 0, 0, page_array) ) 2.736 - { 2.737 - PERROR("Could not allocate memory for PV guest.\n"); 2.738 - goto error_out; 2.739 - } 2.740 - 2.741 - 2.742 - if ( shadow_mode_enabled ) 2.743 - { 2.744 - /* 2.745 - * Enable shadow translate mode. This must happen after 2.746 - * populate physmap because the p2m reservation is based on 2.747 - * the domain's current memory allocation. 2.748 - */ 2.749 - if ( xc_shadow_control(xc_handle, dom, 2.750 - XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE, 2.751 - NULL, 0, NULL, 0, NULL) < 0 ) 2.752 - { 2.753 - PERROR("Could not enable translation mode"); 2.754 - goto error_out; 2.755 - } 2.756 - 2.757 - /* Reinitialise the gpfn->gmfn array. */ 2.758 - for ( i = 0; i < nr_pages; i++ ) 2.759 - page_array[i] = i; 2.760 - } 2.761 - 2.762 - rc = (load_funcs.loadimage)(image, image_size, 2.763 - xc_handle, dom, page_array, 2.764 - &dsi); 2.765 - if ( rc != 0 ) 2.766 - goto error_out; 2.767 - 2.768 - /* 2.769 - * Why do we need this? The number of page-table frames depends on the 2.770 - * size of the bootstrap address space. But the size of the address space 2.771 - * depends on the number of page-table frames (since each one is mapped 2.772 - * read-only). We have a pair of simultaneous equations in two unknowns, 2.773 - * which we solve by exhaustive search. 2.774 - */ 2.775 - v_end = round_pgup(dsi.v_end); 2.776 - if ( v_end == 0 ) 2.777 - { 2.778 - ERROR("End of mapped kernel image too close to end of memory"); 2.779 - goto error_out; 2.780 - } 2.781 - 2.782 - vinitrd_start = v_end; 2.783 - if ( load_initrd(xc_handle, dom, initrd, 2.784 - vinitrd_start - dsi.v_start, page_array) ) 2.785 - goto error_out; 2.786 - if ( !increment_ulong(&v_end, round_pgup(initrd->len)) ) 2.787 - goto error_out; 2.788 - 2.789 - vphysmap_start = v_end; 2.790 - if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) ) 2.791 - goto error_out; 2.792 - vstartinfo_start = v_end; 2.793 - if ( !increment_ulong(&v_end, PAGE_SIZE) ) 2.794 - goto error_out; 2.795 - vstoreinfo_start = v_end; 2.796 - if ( !increment_ulong(&v_end, PAGE_SIZE) ) 2.797 - goto error_out; 2.798 - vconsole_start = v_end; 2.799 - if ( !increment_ulong(&v_end, PAGE_SIZE) ) 2.800 - goto error_out; 2.801 - if ( shadow_mode_enabled ) { 2.802 - vsharedinfo_start = v_end; 2.803 - if ( !increment_ulong(&v_end, PAGE_SIZE) ) 2.804 - goto error_out; 2.805 - } 2.806 - vpt_start = v_end; 2.807 - 2.808 - for ( nr_pt_pages = 2; ; nr_pt_pages++ ) 2.809 - { 2.810 - /* vpt_end = vpt_staret + (nr_pt_pages * PAGE_SIZE); */ 2.811 - vpt_end = vpt_start; 2.812 - if ( !increment_ulong(&vpt_end, nr_pt_pages * PAGE_SIZE) ) 2.813 - goto error_out; 2.814 - 2.815 - vstack_start = vpt_end; 2.816 - /* vstack_end = vstack_start + PAGE_SIZE; */ 2.817 - vstack_end = vstack_start; 2.818 - if ( !increment_ulong(&vstack_end, PAGE_SIZE) ) 2.819 - goto error_out; 2.820 - 2.821 - /* v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); */ 2.822 - v_end = vstack_end; 2.823 - if ( !increment_ulong(&v_end, (1UL<<22)-1) ) 2.824 - goto error_out; 2.825 - v_end &= ~((1UL<<22)-1); 2.826 - 2.827 - if ( (v_end - vstack_end) < (512UL << 10) ) 2.828 - { 2.829 - /* Add extra 4MB to get >= 512kB padding. */ 2.830 - if ( !increment_ulong(&v_end, 1UL << 22) ) 2.831 - goto error_out; 2.832 - } 2.833 - 2.834 -#define NR(_l,_h,_s) \ 2.835 - (((((unsigned long)(_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \ 2.836 - ((unsigned long)(_l) & ~((1UL<<(_s))-1))) >> (_s)) 2.837 -#if defined(__i386__) 2.838 - if ( dsi.pae_kernel != PAEKERN_no ) 2.839 - { 2.840 - if ( (1 + /* # L3 */ 2.841 - NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT_PAE) + /* # L2 */ 2.842 - NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT_PAE) + /* # L1 */ 2.843 - /* Include a fourth mid-level page directory for Xen. */ 2.844 - (v_end <= (3 << L3_PAGETABLE_SHIFT_PAE))) 2.845 - <= nr_pt_pages ) 2.846 - break; 2.847 - } 2.848 - else 2.849 - { 2.850 - if ( (1 + /* # L2 */ 2.851 - NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */ 2.852 - <= nr_pt_pages ) 2.853 - break; 2.854 - } 2.855 -#elif defined(__x86_64__) 2.856 - if ( (1 + /* # L4 */ 2.857 - NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */ 2.858 - NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */ 2.859 - NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */ 2.860 - <= nr_pt_pages ) 2.861 - break; 2.862 -#endif 2.863 - } 2.864 - 2.865 - IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"); 2.866 - IPRINTF(" Loaded kernel: %p->%p\n", _p(dsi.v_kernstart), 2.867 - _p(dsi.v_kernend)); 2.868 - if ( initrd->len ) 2.869 - IPRINTF(" Initial ramdisk: %p->%p\n", _p(vinitrd_start), 2.870 - _p(vinitrd_start + initrd->len)); 2.871 - IPRINTF(" Phys-Mach map: %p\n", _p(vphysmap_start)); 2.872 - IPRINTF(" Start info: %p\n", _p(vstartinfo_start)); 2.873 - IPRINTF(" Store page: %p\n", _p(vstoreinfo_start)); 2.874 - IPRINTF(" Console page: %p\n", _p(vconsole_start)); 2.875 - if ( shadow_mode_enabled ) 2.876 - IPRINTF(" Shared Info page: %p\n", _p(vsharedinfo_start)); 2.877 - IPRINTF(" Page tables: %p\n", _p(vpt_start)); 2.878 - IPRINTF(" Boot stack: %p\n", _p(vstack_start)); 2.879 - IPRINTF(" TOTAL: %p->%p\n", _p(dsi.v_start), _p(v_end)); 2.880 - IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); 2.881 - 2.882 - if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages ) 2.883 - { 2.884 - PERROR("Initial guest OS requires too much space\n" 2.885 - "(%pMB is greater than %luMB limit)\n", 2.886 - _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT)); 2.887 - goto error_out; 2.888 - } 2.889 - 2.890 -#if defined(__i386__) 2.891 - if ( dsi.pae_kernel != PAEKERN_no ) 2.892 - rc = setup_pg_tables_pae(xc_handle, dom, ctxt, 2.893 - dsi.v_start, v_end, 2.894 - page_array, vpt_start, vpt_end, 2.895 - shadow_mode_enabled, dsi.pae_kernel); 2.896 - else 2.897 - rc = setup_pg_tables(xc_handle, dom, ctxt, 2.898 - dsi.v_start, v_end, 2.899 - page_array, vpt_start, vpt_end, 2.900 - shadow_mode_enabled); 2.901 -#endif 2.902 -#if defined(__x86_64__) 2.903 - rc = setup_pg_tables_64(xc_handle, dom, ctxt, 2.904 - dsi.v_start, v_end, 2.905 - page_array, vpt_start, vpt_end, 2.906 - shadow_mode_enabled); 2.907 -#endif 2.908 - if ( rc != 0 ) 2.909 - goto error_out; 2.910 - 2.911 - /* 2.912 - * Pin down l2tab addr as page dir page - causes hypervisor to provide 2.913 - * correct protection for the page 2.914 - */ 2.915 - if ( !shadow_mode_enabled ) 2.916 - { 2.917 -#if defined(__i386__) 2.918 - if ( dsi.pae_kernel != PAEKERN_no ) 2.919 - { 2.920 - if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE, 2.921 - xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) 2.922 - goto error_out; 2.923 - } 2.924 - else 2.925 - { 2.926 - if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE, 2.927 - xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) 2.928 - goto error_out; 2.929 - } 2.930 -#elif defined(__x86_64__) 2.931 - /* 2.932 - * Pin down l4tab addr as page dir page - causes hypervisor to provide 2.933 - * correct protection for the page 2.934 - */ 2.935 - if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE, 2.936 - xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) 2.937 - goto error_out; 2.938 -#endif 2.939 - } 2.940 - 2.941 - /* Write the phys->machine table entries (machine->phys already done). */ 2.942 - physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT; 2.943 - physmap = physmap_e = xc_map_foreign_range( 2.944 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 2.945 - page_array[physmap_pfn++]); 2.946 - for ( count = 0; count < nr_pages; count++ ) 2.947 - { 2.948 - *physmap_e++ = page_array[count]; 2.949 - if ( ((unsigned long)physmap_e & (PAGE_SIZE-1)) == 0 ) 2.950 - { 2.951 - munmap(physmap, PAGE_SIZE); 2.952 - physmap = physmap_e = xc_map_foreign_range( 2.953 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 2.954 - page_array[physmap_pfn++]); 2.955 - } 2.956 - } 2.957 - munmap(physmap, PAGE_SIZE); 2.958 - 2.959 - if ( shadow_mode_enabled ) 2.960 - { 2.961 - struct xen_add_to_physmap xatp; 2.962 - 2.963 - guest_shared_info_mfn = (vsharedinfo_start-dsi.v_start) >> PAGE_SHIFT; 2.964 - 2.965 - /* Map shared info frame into guest physmap. */ 2.966 - xatp.domid = dom; 2.967 - xatp.space = XENMAPSPACE_shared_info; 2.968 - xatp.idx = 0; 2.969 - xatp.gpfn = guest_shared_info_mfn; 2.970 - rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp); 2.971 - if ( rc != 0 ) 2.972 - { 2.973 - PERROR("Cannot map shared info pfn"); 2.974 - goto error_out; 2.975 - } 2.976 - 2.977 - /* Map grant table frames into guest physmap. */ 2.978 - for ( i = 0; ; i++ ) 2.979 - { 2.980 - xatp.domid = dom; 2.981 - xatp.space = XENMAPSPACE_grant_table; 2.982 - xatp.idx = i; 2.983 - xatp.gpfn = nr_pages + i; 2.984 - rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp); 2.985 - if ( rc != 0 ) 2.986 - { 2.987 - if ( errno == EINVAL ) 2.988 - break; /* done all grant tables */ 2.989 - PERROR("Cannot map grant table pfn"); 2.990 - goto error_out; 2.991 - } 2.992 - } 2.993 - } 2.994 - else 2.995 - { 2.996 - guest_shared_info_mfn = shared_info_frame; 2.997 - } 2.998 - 2.999 - *store_mfn = page_array[(vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT]; 2.1000 - *console_mfn = page_array[(vconsole_start-dsi.v_start) >> PAGE_SHIFT]; 2.1001 - if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) || 2.1002 - xc_clear_domain_page(xc_handle, dom, *console_mfn) ) 2.1003 - goto error_out; 2.1004 - if ( shadow_mode_enabled ) 2.1005 - { 2.1006 - guest_store_mfn = (vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT; 2.1007 - guest_console_mfn = (vconsole_start-dsi.v_start) >> PAGE_SHIFT; 2.1008 - } 2.1009 - else 2.1010 - { 2.1011 - guest_store_mfn = *store_mfn; 2.1012 - guest_console_mfn = *console_mfn; 2.1013 - } 2.1014 - 2.1015 - start_info = xc_map_foreign_range( 2.1016 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 2.1017 - page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]); 2.1018 - /*shared_info, start_info */ 2.1019 - memset(start_info, 0, sizeof(*start_info)); 2.1020 - rc = xc_version(xc_handle, XENVER_version, NULL); 2.1021 - sprintf(start_info->magic, "xen-%i.%i-x86_%d%s", 2.1022 - rc >> 16, rc & (0xFFFF), (unsigned int)sizeof(long)*8, 2.1023 - (dsi.pae_kernel != PAEKERN_no) ? "p" : ""); 2.1024 - start_info->nr_pages = nr_pages; 2.1025 - start_info->shared_info = guest_shared_info_mfn << PAGE_SHIFT; 2.1026 - start_info->flags = flags; 2.1027 - start_info->pt_base = vpt_start; 2.1028 - start_info->nr_pt_frames = nr_pt_pages; 2.1029 - start_info->mfn_list = vphysmap_start; 2.1030 - start_info->store_mfn = guest_store_mfn; 2.1031 - start_info->store_evtchn = store_evtchn; 2.1032 - start_info->console.domU.mfn = guest_console_mfn; 2.1033 - start_info->console.domU.evtchn = console_evtchn; 2.1034 - if ( initrd->len != 0 ) 2.1035 - { 2.1036 - start_info->mod_start = vinitrd_start; 2.1037 - start_info->mod_len = initrd->len; 2.1038 - } 2.1039 - if ( cmdline != NULL ) 2.1040 - { 2.1041 - strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE); 2.1042 - start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0'; 2.1043 - } 2.1044 - munmap(start_info, PAGE_SIZE); 2.1045 - 2.1046 - /* shared_info page starts its life empty. */ 2.1047 - shared_info = xc_map_foreign_range( 2.1048 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame); 2.1049 - memset(shared_info, 0, PAGE_SIZE); 2.1050 - /* Mask all upcalls... */ 2.1051 - for ( i = 0; i < MAX_VIRT_CPUS; i++ ) 2.1052 - shared_info->vcpu_info[i].evtchn_upcall_mask = 1; 2.1053 - 2.1054 - munmap(shared_info, PAGE_SIZE); 2.1055 - 2.1056 - hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, 2.1057 - &hypercall_page_defined); 2.1058 - if ( hypercall_page_defined ) 2.1059 - { 2.1060 - unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT; 2.1061 - if ( pfn >= nr_pages ) 2.1062 - goto error_out; 2.1063 - domctl.domain = (domid_t)dom; 2.1064 - domctl.u.hypercall_init.gmfn = page_array[pfn]; 2.1065 - domctl.cmd = XEN_DOMCTL_hypercall_init; 2.1066 - if ( xc_domctl(xc_handle, &domctl) ) 2.1067 - goto error_out; 2.1068 - } 2.1069 - 2.1070 - free(page_array); 2.1071 - 2.1072 - *pvsi = vstartinfo_start; 2.1073 - *pvss = vstack_start; 2.1074 - *pvke = dsi.v_kernentry; 2.1075 - 2.1076 - return 0; 2.1077 - 2.1078 - error_out: 2.1079 - free(page_array); 2.1080 - return -1; 2.1081 -} 2.1082 -#endif 2.1083 - 2.1084 -static int xc_linux_build_internal(int xc_handle, 2.1085 - uint32_t domid, 2.1086 - unsigned int mem_mb, 2.1087 - const char *image, 2.1088 - unsigned long image_size, 2.1089 - struct initrd_info *initrd, 2.1090 - const char *cmdline, 2.1091 - const char *features, 2.1092 - unsigned long flags, 2.1093 - unsigned int store_evtchn, 2.1094 - unsigned long *store_mfn, 2.1095 - unsigned int console_evtchn, 2.1096 - unsigned long *console_mfn) 2.1097 -{ 2.1098 - struct xen_domctl launch_domctl; 2.1099 - DECLARE_DOMCTL; 2.1100 - int rc; 2.1101 - struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt; 2.1102 - unsigned long vstartinfo_start, vkern_entry, vstack_start; 2.1103 - uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, }; 2.1104 - 2.1105 - if ( features != NULL ) 2.1106 - { 2.1107 - if ( !parse_features(features, features_bitmap, NULL) ) 2.1108 - { 2.1109 - PERROR("Failed to parse configured features\n"); 2.1110 - goto error_out; 2.1111 - } 2.1112 - } 2.1113 - 2.1114 - memset(ctxt, 0, sizeof(*ctxt)); 2.1115 - 2.1116 - if ( lock_pages(ctxt, sizeof(*ctxt) ) ) 2.1117 - { 2.1118 - PERROR("%s: ctxt lock failed", __func__); 2.1119 - return 1; 2.1120 - } 2.1121 - 2.1122 - domctl.cmd = XEN_DOMCTL_getdomaininfo; 2.1123 - domctl.domain = (domid_t)domid; 2.1124 - if ( (xc_domctl(xc_handle, &domctl) < 0) || 2.1125 - ((uint16_t)domctl.domain != domid) ) 2.1126 - { 2.1127 - PERROR("Could not get info on domain"); 2.1128 - goto error_out; 2.1129 - } 2.1130 - 2.1131 - if ( setup_guest(xc_handle, domid, image, image_size, 2.1132 - initrd, 2.1133 - mem_mb << (20 - PAGE_SHIFT), 2.1134 - &vstartinfo_start, &vkern_entry, 2.1135 - &vstack_start, ctxt, cmdline, 2.1136 - domctl.u.getdomaininfo.shared_info_frame, 2.1137 - flags, store_evtchn, store_mfn, 2.1138 - console_evtchn, console_mfn, 2.1139 - features_bitmap) < 0 ) 2.1140 - { 2.1141 - goto error_out; 2.1142 - } 2.1143 - 2.1144 -#ifdef __ia64__ 2.1145 - /* based on new_thread in xen/arch/ia64/domain.c */ 2.1146 - ctxt->user_regs.cr_iip = vkern_entry; 2.1147 - ctxt->user_regs.cr_ifs = 1UL << 63; 2.1148 - ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default(); 2.1149 -#else /* x86 */ 2.1150 - /* 2.1151 - * Initial register values: 2.1152 - * DS,ES,FS,GS = FLAT_KERNEL_DS 2.1153 - * CS:EIP = FLAT_KERNEL_CS:start_pc 2.1154 - * SS:ESP = FLAT_KERNEL_DS:start_stack 2.1155 - * ESI = start_info 2.1156 - * [EAX,EBX,ECX,EDX,EDI,EBP are zero] 2.1157 - * EFLAGS = IF | 2 (bit 1 is reserved and should always be 1) 2.1158 - */ 2.1159 - ctxt->user_regs.ds = FLAT_KERNEL_DS; 2.1160 - ctxt->user_regs.es = FLAT_KERNEL_DS; 2.1161 - ctxt->user_regs.fs = FLAT_KERNEL_DS; 2.1162 - ctxt->user_regs.gs = FLAT_KERNEL_DS; 2.1163 - ctxt->user_regs.ss = FLAT_KERNEL_SS; 2.1164 - ctxt->user_regs.cs = FLAT_KERNEL_CS; 2.1165 - ctxt->user_regs.eip = vkern_entry; 2.1166 - ctxt->user_regs.esp = vstack_start + PAGE_SIZE; 2.1167 - ctxt->user_regs.esi = vstartinfo_start; 2.1168 - ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */ 2.1169 - 2.1170 - ctxt->flags = VGCF_IN_KERNEL; 2.1171 - 2.1172 - ctxt->kernel_ss = ctxt->user_regs.ss; 2.1173 - ctxt->kernel_sp = ctxt->user_regs.esp; 2.1174 -#endif /* x86 */ 2.1175 - 2.1176 - memset(&launch_domctl, 0, sizeof(launch_domctl)); 2.1177 - 2.1178 - launch_domctl.domain = (domid_t)domid; 2.1179 - launch_domctl.u.vcpucontext.vcpu = 0; 2.1180 - set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt); 2.1181 - 2.1182 - launch_domctl.cmd = XEN_DOMCTL_setvcpucontext; 2.1183 - rc = xc_domctl(xc_handle, &launch_domctl); 2.1184 - 2.1185 - return rc; 2.1186 - 2.1187 - error_out: 2.1188 - return -1; 2.1189 -} 2.1190 - 2.1191 -int xc_linux_build_mem(int xc_handle, 2.1192 - uint32_t domid, 2.1193 - unsigned int mem_mb, 2.1194 - const char *image_buffer, 2.1195 - unsigned long image_size, 2.1196 - const char *initrd, 2.1197 - unsigned long initrd_len, 2.1198 - const char *cmdline, 2.1199 - const char *features, 2.1200 - unsigned long flags, 2.1201 - unsigned int store_evtchn, 2.1202 - unsigned long *store_mfn, 2.1203 - unsigned int console_evtchn, 2.1204 - unsigned long *console_mfn) 2.1205 -{ 2.1206 - int sts; 2.1207 - char *img_buf; 2.1208 - unsigned long img_len; 2.1209 - struct initrd_info initrd_info = { .type = INITRD_none }; 2.1210 - 2.1211 - /* A kernel buffer is required */ 2.1212 - if ( (image_buffer == NULL) || (image_size == 0) ) 2.1213 - { 2.1214 - ERROR("kernel image buffer not present"); 2.1215 - return -1; 2.1216 - } 2.1217 - 2.1218 - /* If it's gzipped, inflate it; otherwise, use as is */ 2.1219 - /* xc_inflate_buffer may return the same buffer pointer if */ 2.1220 - /* the buffer is already inflated */ 2.1221 - img_buf = xc_inflate_buffer(image_buffer, image_size, &img_len); 2.1222 - if ( img_buf == NULL ) 2.1223 - { 2.1224 - ERROR("unable to inflate kernel image buffer"); 2.1225 - return -1; 2.1226 - } 2.1227 - 2.1228 - /* RAM disks are optional; if we get one, inflate it */ 2.1229 - if ( initrd != NULL ) 2.1230 - { 2.1231 - initrd_info.type = INITRD_mem; 2.1232 - initrd_info.u.mem_addr = xc_inflate_buffer( 2.1233 - initrd, initrd_len, &initrd_info.len); 2.1234 - if ( initrd_info.u.mem_addr == NULL ) 2.1235 - { 2.1236 - ERROR("unable to inflate ram disk buffer"); 2.1237 - sts = -1; 2.1238 - goto out; 2.1239 - } 2.1240 - } 2.1241 - 2.1242 - sts = xc_linux_build_internal(xc_handle, domid, mem_mb, img_buf, img_len, 2.1243 - &initrd_info, cmdline, features, flags, 2.1244 - store_evtchn, store_mfn, 2.1245 - console_evtchn, console_mfn); 2.1246 - 2.1247 - out: 2.1248 - /* The inflation routines may pass back the same buffer so be */ 2.1249 - /* sure that we have a buffer and that it's not the one passed in. */ 2.1250 - /* Don't unnecessarily annoy/surprise/confound the caller */ 2.1251 - if ( (img_buf != NULL) && (img_buf != image_buffer) ) 2.1252 - free(img_buf); 2.1253 - if ( (initrd_info.u.mem_addr != NULL) && 2.1254 - (initrd_info.u.mem_addr != initrd) ) 2.1255 - free(initrd_info.u.mem_addr); 2.1256 - 2.1257 - return sts; 2.1258 -} 2.1259 - 2.1260 -int xc_linux_build(int xc_handle, 2.1261 - uint32_t domid, 2.1262 - unsigned int mem_mb, 2.1263 - const char *image_name, 2.1264 - const char *initrd_name, 2.1265 - const char *cmdline, 2.1266 - const char *features, 2.1267 - unsigned long flags, 2.1268 - unsigned int store_evtchn, 2.1269 - unsigned long *store_mfn, 2.1270 - unsigned int console_evtchn, 2.1271 - unsigned long *console_mfn) 2.1272 -{ 2.1273 - char *image = NULL; 2.1274 - unsigned long image_size; 2.1275 - struct initrd_info initrd_info = { .type = INITRD_none }; 2.1276 - int fd = -1, sts = -1; 2.1277 - 2.1278 - if ( (image_name == NULL) || 2.1279 - ((image = xc_read_image(image_name, &image_size)) == NULL )) 2.1280 - return -1; 2.1281 - 2.1282 - if ( (initrd_name != NULL) && (strlen(initrd_name) != 0) ) 2.1283 - { 2.1284 - initrd_info.type = INITRD_file; 2.1285 - 2.1286 - if ( (fd = open(initrd_name, O_RDONLY)) < 0 ) 2.1287 - { 2.1288 - PERROR("Could not open the initial ramdisk image"); 2.1289 - goto error_out; 2.1290 - } 2.1291 - 2.1292 - if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL ) 2.1293 - { 2.1294 - PERROR("Could not allocate decompression state for initrd"); 2.1295 - goto error_out; 2.1296 - } 2.1297 - } 2.1298 - 2.1299 - sts = xc_linux_build_internal(xc_handle, domid, mem_mb, image, image_size, 2.1300 - &initrd_info, cmdline, features, flags, 2.1301 - store_evtchn, store_mfn, 2.1302 - console_evtchn, console_mfn); 2.1303 - 2.1304 - error_out: 2.1305 - free(image); 2.1306 - if ( initrd_info.type == INITRD_file && initrd_info.u.file_handle ) 2.1307 - gzclose(initrd_info.u.file_handle); 2.1308 - else if ( fd >= 0 ) 2.1309 - close(fd); 2.1310 - 2.1311 - return sts; 2.1312 -} 2.1313 - 2.1314 -/* 2.1315 - * Local variables: 2.1316 - * mode: C 2.1317 - * c-set-style: "BSD" 2.1318 - * c-basic-offset: 4 2.1319 - * tab-width: 4 2.1320 - * indent-tabs-mode: nil 2.1321 - * End: 2.1322 - */
3.1 --- a/tools/libxc/xc_load_bin.c Wed Feb 14 12:18:32 2007 -0800 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,306 +0,0 @@ 3.4 -/****************************************************************************** 3.5 - * xc_bin_load.c 3.6 - * 3.7 - * Based on xc_elf_load.c 3.8 - * 3.9 - * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are 3.10 - * present. The only requirement is that it must have a xen_bin_image table 3.11 - * somewhere in the first 8192 bytes, starting on a 32-bit aligned address. 3.12 - * Those familiar with the multiboot specification should recognize this, it's 3.13 - * (almost) the same as the multiboot header. 3.14 - * The layout of the xen_bin_image table is: 3.15 - * 3.16 - * Offset Type Name Note 3.17 - * 0 uint32_t magic required 3.18 - * 4 uint32_t flags required 3.19 - * 8 uint32_t checksum required 3.20 - * 12 uint32_t header_addr required 3.21 - * 16 uint32_t load_addr required 3.22 - * 20 uint32_t load_end_addr required 3.23 - * 24 uint32_t bss_end_addr required 3.24 - * 28 uint32_t entry_addr required 3.25 - * 3.26 - * - magic 3.27 - * Magic number identifying the table. For images to be loaded by Xen 3, the 3.28 - * magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set). 3.29 - * - flags 3.30 - * bit 0: indicates whether the image needs to be loaded on a page boundary 3.31 - * bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate 3.32 - * that memory info should be passed to the image) 3.33 - * bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate 3.34 - * that the bootloader should pass video mode info to the image) 3.35 - * bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate 3.36 - * that the values in the fields header_addr - entry_addr are 3.37 - * valid) 3.38 - * All other bits should be set to 0. 3.39 - * - checksum 3.40 - * When added to "magic" and "flags", the resulting value should be 0. 3.41 - * - header_addr 3.42 - * Contains the virtual address corresponding to the beginning of the 3.43 - * table - the memory location at which the magic value is supposed to be 3.44 - * loaded. This field serves to synchronize the mapping between OS image 3.45 - * offsets and virtual memory addresses. 3.46 - * - load_addr 3.47 - * Contains the virtual address of the beginning of the text segment. The 3.48 - * offset in the OS image file at which to start loading is defined by the 3.49 - * offset at which the table was found, minus (header addr - load addr). 3.50 - * load addr must be less than or equal to header addr. 3.51 - * - load_end_addr 3.52 - * Contains the virtual address of the end of the data segment. 3.53 - * (load_end_addr - load_addr) specifies how much data to load. This implies 3.54 - * that the text and data segments must be consecutive in the OS image. If 3.55 - * this field is zero, the domain builder assumes that the text and data 3.56 - * segments occupy the whole OS image file. 3.57 - * - bss_end_addr 3.58 - * Contains the virtual address of the end of the bss segment. The domain 3.59 - * builder initializes this area to zero, and reserves the memory it occupies 3.60 - * to avoid placing boot modules and other data relevant to the loaded image 3.61 - * in that area. If this field is zero, the domain builder assumes that no bss 3.62 - * segment is present. 3.63 - * - entry_addr 3.64 - * The virtual address at which to start execution of the loaded image. 3.65 - * 3.66 - * Some of the field descriptions were copied from "The Multiboot 3.67 - * Specification", Copyright 1995, 96 Bryan Ford <baford@cs.utah.edu>, 3.68 - * Erich Stefan Boleyn <erich@uruk.org> Copyright 1999, 2000, 2001, 2002 3.69 - * Free Software Foundation, Inc. 3.70 - */ 3.71 - 3.72 -#include "xg_private.h" 3.73 -#include <stdlib.h> 3.74 - 3.75 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) 3.76 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) 3.77 - 3.78 -#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) 3.79 -#define round_pgdown(_p) ((_p)&PAGE_MASK) 3.80 - 3.81 -struct xen_bin_image_table 3.82 -{ 3.83 - unsigned long magic; 3.84 - unsigned long flags; 3.85 - unsigned long checksum; 3.86 - unsigned long header_addr; 3.87 - unsigned long load_addr; 3.88 - unsigned long load_end_addr; 3.89 - unsigned long bss_end_addr; 3.90 - unsigned long entry_addr; 3.91 -}; 3.92 - 3.93 -#define XEN_REACTOS_MAGIC3 0x336ec578 3.94 - 3.95 -#define XEN_REACTOS_FLAG_ALIGN4K 0x00000001 3.96 -#define XEN_REACTOS_FLAG_NEEDMEMINFO 0x00000002 3.97 -#define XEN_REACTOS_FLAG_NEEDVIDINFO 0x00000004 3.98 -#define XEN_REACTOS_FLAG_ADDRSVALID 0x00010000 3.99 - 3.100 -/* Flags we test for */ 3.101 -#define FLAGS_MASK ((~ 0) & (~ XEN_REACTOS_FLAG_ALIGN4K)) 3.102 -#define FLAGS_REQUIRED XEN_REACTOS_FLAG_ADDRSVALID 3.103 - 3.104 -static const struct xen_bin_image_table * 3.105 -findtable(const char *image, unsigned long image_size); 3.106 -static int 3.107 -parsebinimage( 3.108 - const char *image, unsigned long image_size, 3.109 - struct domain_setup_info *dsi); 3.110 -static int 3.111 -loadbinimage( 3.112 - const char *image, unsigned long image_size, int xch, uint32_t dom, 3.113 - xen_pfn_t *parray, struct domain_setup_info *dsi); 3.114 - 3.115 -int probe_bin(const char *image, 3.116 - unsigned long image_size, 3.117 - struct load_funcs *load_funcs) 3.118 -{ 3.119 - if ( findtable(image, image_size) == NULL ) 3.120 - return -EINVAL; 3.121 - 3.122 - load_funcs->parseimage = parsebinimage; 3.123 - load_funcs->loadimage = loadbinimage; 3.124 - 3.125 - return 0; 3.126 -} 3.127 - 3.128 -static const struct xen_bin_image_table * 3.129 -findtable(const char *image, unsigned long image_size) 3.130 -{ 3.131 - const struct xen_bin_image_table *table; 3.132 - const unsigned long *probe_ptr; 3.133 - unsigned probe_index; 3.134 - unsigned probe_count; 3.135 - 3.136 - /* Don't go outside the image */ 3.137 - if ( image_size < sizeof(struct xen_bin_image_table) ) 3.138 - return NULL; 3.139 - 3.140 - probe_count = image_size; 3.141 - /* Restrict to first 8k */ 3.142 - if ( probe_count > 8192 ) 3.143 - probe_count = 8192; 3.144 - probe_count = (probe_count - sizeof(struct xen_bin_image_table)) / 3.145 - sizeof(unsigned long); 3.146 - 3.147 - /* Search for the magic header */ 3.148 - probe_ptr = (const unsigned long *) image; 3.149 - table = NULL; 3.150 - for ( probe_index = 0; probe_index < probe_count; probe_index++ ) 3.151 - { 3.152 - if ( XEN_REACTOS_MAGIC3 == *probe_ptr ) 3.153 - { 3.154 - table = (const struct xen_bin_image_table *) probe_ptr; 3.155 - /* Checksum correct? */ 3.156 - if ( 0 == table->magic + table->flags + table->checksum ) 3.157 - { 3.158 - return table; 3.159 - } 3.160 - } 3.161 - probe_ptr++; 3.162 - } 3.163 - 3.164 - return NULL; 3.165 -} 3.166 - 3.167 -static int parsebinimage(const char *image, 3.168 - unsigned long image_size, 3.169 - struct domain_setup_info *dsi) 3.170 -{ 3.171 - const struct xen_bin_image_table *image_info; 3.172 - unsigned long start_addr; 3.173 - unsigned long end_addr; 3.174 - 3.175 - image_info = findtable(image, image_size); 3.176 - if ( NULL == image_info ) 3.177 - { 3.178 - ERROR("Image does not have a valid xen_bin_image_table table."); 3.179 - return -EINVAL; 3.180 - } 3.181 - 3.182 - /* Check the flags */ 3.183 - if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) ) 3.184 - { 3.185 - ERROR("xen_bin_image_table flags required 0x%08x found 0x%08lx", 3.186 - FLAGS_REQUIRED, image_info->flags & FLAGS_MASK); 3.187 - return -EINVAL; 3.188 - } 3.189 - 3.190 - /* Sanity check on the addresses */ 3.191 - if ( image_info->header_addr < image_info->load_addr || 3.192 - ((const char *) image_info - image) < 3.193 - (image_info->header_addr - image_info->load_addr) ) 3.194 - { 3.195 - ERROR("Invalid header_addr."); 3.196 - return -EINVAL; 3.197 - } 3.198 - start_addr = image_info->header_addr - ((const char *) image_info - image); 3.199 - if ( 0 != image_info->load_end_addr && 3.200 - ( image_info->load_end_addr < image_info->load_end_addr || 3.201 - start_addr + image_size < image_info->load_end_addr ) ) 3.202 - { 3.203 - ERROR("Invalid load_end_addr"); 3.204 - return -EINVAL; 3.205 - } 3.206 - end_addr = (0 == image_info->load_end_addr ? start_addr + image_size : 3.207 - image_info->load_end_addr); 3.208 - if ( 0 != image_info->bss_end_addr && 3.209 - image_info->bss_end_addr < end_addr ) 3.210 - { 3.211 - ERROR("Invalid bss_end_addr"); 3.212 - return -EINVAL; 3.213 - } 3.214 - 3.215 - dsi->v_start = image_info->load_addr; 3.216 - if ( 0 != image_info->bss_end_addr ) 3.217 - { 3.218 - dsi->v_end = image_info->bss_end_addr; 3.219 - } 3.220 - else if ( 0 != image_info->load_end_addr ) 3.221 - { 3.222 - dsi->v_end = image_info->load_end_addr; 3.223 - } 3.224 - else 3.225 - { 3.226 - dsi->v_end = image_info->load_addr + image_size - 3.227 - (((const char *) image_info - image) - 3.228 - (image_info->header_addr - image_info->load_addr)); 3.229 - } 3.230 - dsi->v_kernstart = dsi->v_start; 3.231 - dsi->v_kernend = dsi->v_end; 3.232 - dsi->v_kernentry = image_info->entry_addr; 3.233 - dsi->__xen_guest_string = NULL; 3.234 - 3.235 - return 0; 3.236 -} 3.237 - 3.238 -static int 3.239 -loadbinimage( 3.240 - const char *image, unsigned long image_size, int xch, uint32_t dom, 3.241 - xen_pfn_t *parray, struct domain_setup_info *dsi) 3.242 -{ 3.243 - unsigned long size; 3.244 - char *va; 3.245 - unsigned long done, chunksz; 3.246 - const struct xen_bin_image_table *image_info; 3.247 - 3.248 - image_info = findtable(image, image_size); 3.249 - if ( NULL == image_info ) 3.250 - { 3.251 - ERROR("Image does not have a valid xen_bin_image_table table."); 3.252 - return -EINVAL; 3.253 - } 3.254 - 3.255 - /* Determine image size */ 3.256 - if ( 0 == image_info->load_end_addr ) 3.257 - { 3.258 - size = image_size - (((const char *)image_info - image) - 3.259 - (image_info->header_addr - 3.260 - image_info->load_addr)); 3.261 - } 3.262 - else 3.263 - { 3.264 - size = image_info->load_end_addr - image_info->load_addr; 3.265 - } 3.266 - 3.267 - /* It's possible that we need to skip the first part of the image */ 3.268 - image += ((const char *)image_info - image) - 3.269 - (image_info->header_addr - image_info->load_addr); 3.270 - 3.271 - for ( done = 0; done < size; done += chunksz ) 3.272 - { 3.273 - va = xc_map_foreign_range( 3.274 - xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]); 3.275 - chunksz = size - done; 3.276 - if ( chunksz > PAGE_SIZE ) 3.277 - chunksz = PAGE_SIZE; 3.278 - memcpy(va, image + done, chunksz); 3.279 - munmap(va, PAGE_SIZE); 3.280 - } 3.281 - 3.282 - if ( 0 != image_info->bss_end_addr && 3.283 - image_info->load_addr + size < image_info->bss_end_addr ) 3.284 - { 3.285 - size = image_info->bss_end_addr - image_info->load_addr; 3.286 - } 3.287 - for ( ; done < size; done += chunksz ) 3.288 - { 3.289 - va = xc_map_foreign_range( 3.290 - xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]); 3.291 - chunksz = size - done; 3.292 - if ( chunksz > (PAGE_SIZE - (done & (PAGE_SIZE-1))) ) 3.293 - chunksz = PAGE_SIZE - (done & (PAGE_SIZE-1)); 3.294 - memset(va + (done & (PAGE_SIZE-1)), 0, chunksz); 3.295 - munmap(va, PAGE_SIZE); 3.296 - } 3.297 - 3.298 - return 0; 3.299 -} 3.300 - 3.301 -/* 3.302 - * Local variables: 3.303 - * mode: C 3.304 - * c-set-style: "BSD" 3.305 - * c-basic-offset: 4 3.306 - * tab-width: 4 3.307 - * indent-tabs-mode: nil 3.308 - * End: 3.309 - */
4.1 --- a/tools/libxc/xc_load_elf.c Wed Feb 14 12:18:32 2007 -0800 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,684 +0,0 @@ 4.4 -/****************************************************************************** 4.5 - * xc_elf_load.c 4.6 - */ 4.7 - 4.8 -#include "xg_private.h" 4.9 -#include "xc_elf.h" 4.10 -#include <stdlib.h> 4.11 -#include <inttypes.h> 4.12 - 4.13 -#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) 4.14 -#define round_pgdown(_p) ((_p)&PAGE_MASK) 4.15 - 4.16 -static int 4.17 -parseelfimage( 4.18 - const char *image, unsigned long image_size, 4.19 - struct domain_setup_info *dsi); 4.20 -static int 4.21 -loadelfimage( 4.22 - const char *image, unsigned long image_size, int xch, uint32_t dom, 4.23 - xen_pfn_t *parray, struct domain_setup_info *dsi); 4.24 -static int 4.25 -loadelfsymtab( 4.26 - const char *image, int xch, uint32_t dom, xen_pfn_t *parray, 4.27 - struct domain_setup_info *dsi); 4.28 - 4.29 -/* 4.30 - * Elf header attributes we require for each supported host platform. 4.31 - * These are checked in parseelfimage(). 4.32 - */ 4.33 -#if defined(__ia64__) 4.34 -#define ELFCLASS ELFCLASS64 4.35 -#define ELFCLASS_DESC "64-bit" 4.36 - 4.37 -#define ELFDATA ELFDATA2LSB 4.38 -#define ELFDATA_DESC "Little-Endian" 4.39 - 4.40 -#define ELFMACHINE EM_IA_64 4.41 -#define ELFMACHINE_DESC "ia64" 4.42 - 4.43 - 4.44 -#elif defined(__i386__) 4.45 -#define ELFCLASS ELFCLASS32 4.46 -#define ELFCLASS_DESC "32-bit" 4.47 - 4.48 -#define ELFDATA ELFDATA2LSB 4.49 -#define ELFDATA_DESC "Little-Endian" 4.50 - 4.51 -#define ELFMACHINE EM_386 4.52 -#define ELFMACHINE_DESC "i386" 4.53 - 4.54 - 4.55 -#elif defined(__x86_64__) 4.56 -#define ELFCLASS ELFCLASS64 4.57 -#define ELFCLASS_DESC "64-bit" 4.58 - 4.59 -#define ELFDATA ELFDATA2LSB 4.60 -#define ELFDATA_DESC "Little-Endian" 4.61 - 4.62 -#define ELFMACHINE EM_X86_64 4.63 -#define ELFMACHINE_DESC "x86_64" 4.64 - 4.65 - 4.66 -#elif defined(__powerpc__) 4.67 -#define ELFCLASS ELFCLASS64 4.68 -#define ELFCLASS_DESC "64-bit" 4.69 - 4.70 -#define ELFDATA ELFDATA2MSB 4.71 -#define ELFDATA_DESC "Big-Endian" 4.72 - 4.73 -#define ELFMACHINE EM_PPC64 4.74 -#define ELFMACHINE_DESC "ppc64" 4.75 -#endif 4.76 - 4.77 -int probe_elf(const char *image, 4.78 - unsigned long image_size, 4.79 - struct load_funcs *load_funcs) 4.80 -{ 4.81 - const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image; 4.82 - 4.83 - if ( !IS_ELF(*ehdr) ) 4.84 - return -EINVAL; 4.85 - 4.86 - load_funcs->parseimage = parseelfimage; 4.87 - load_funcs->loadimage = loadelfimage; 4.88 - 4.89 - return 0; 4.90 -} 4.91 - 4.92 -static inline int is_loadable_phdr(const Elf_Phdr *phdr) 4.93 -{ 4.94 - return ((phdr->p_type == PT_LOAD) && 4.95 - ((phdr->p_flags & (PF_W|PF_X)) != 0)); 4.96 -} 4.97 - 4.98 -/* 4.99 - * Fallback for kernels containing only the legacy __xen_guest string 4.100 - * and no ELF notes. 4.101 - */ 4.102 -static int is_xen_guest_section(const Elf_Shdr *shdr, const char *shstrtab) 4.103 -{ 4.104 - return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0; 4.105 -} 4.106 - 4.107 -static const char *xen_guest_lookup( 4.108 - const struct domain_setup_info *dsi, int type) 4.109 -{ 4.110 - const char *xenguest_fallbacks[] = { 4.111 - [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=", 4.112 - [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=", 4.113 - [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=", 4.114 - [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=", 4.115 - [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=", 4.116 - [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=", 4.117 - [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=", 4.118 - [XEN_ELFNOTE_LOADER] = "LOADER=", 4.119 - [XEN_ELFNOTE_PAE_MODE] = "PAE=", 4.120 - [XEN_ELFNOTE_FEATURES] = "FEATURES=", 4.121 - [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=", 4.122 - }; 4.123 - const char *fallback; 4.124 - const char *p; 4.125 - 4.126 - if ( !dsi->__xen_guest_string ) 4.127 - return NULL; 4.128 - 4.129 - if ( type > sizeof(xenguest_fallbacks) ) 4.130 - return NULL; 4.131 - 4.132 - if ( (fallback = xenguest_fallbacks[type]) == NULL ) 4.133 - return NULL; 4.134 - 4.135 - if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL ) 4.136 - return NULL; 4.137 - 4.138 - return p + strlen(fallback); 4.139 -} 4.140 - 4.141 -static const char *xen_guest_string( 4.142 - const struct domain_setup_info *dsi, int type) 4.143 -{ 4.144 - const char *p = xen_guest_lookup(dsi, type); 4.145 - 4.146 - /* 4.147 - * We special case this since the __xen_guest_section treats the 4.148 - * mere precense of the BSD_SYMTAB string as true or false. 4.149 - */ 4.150 - if ( type == XEN_ELFNOTE_BSD_SYMTAB ) 4.151 - return p ? "yes" : "no"; 4.152 - 4.153 - return p; 4.154 -} 4.155 - 4.156 -static unsigned long long xen_guest_numeric( 4.157 - const struct domain_setup_info *dsi, int type, int *defined) 4.158 -{ 4.159 - const char *p = xen_guest_lookup(dsi, type); 4.160 - unsigned long long value; 4.161 - 4.162 - if ( p == NULL ) 4.163 - return 0; 4.164 - 4.165 - errno = 0; 4.166 - value = strtoull(p, NULL, 0); 4.167 - if ( errno < 0 ) 4.168 - return 0; 4.169 - 4.170 - /* We special case this since __xen_guest_section contains a PFN 4.171 - * for this field not a virtual address. 4.172 - */ 4.173 - if (type == XEN_ELFNOTE_HYPERCALL_PAGE) 4.174 - value = dsi->v_start + (value<<PAGE_SHIFT); 4.175 - 4.176 - *defined = 1; 4.177 - return value; 4.178 -} 4.179 - 4.180 -/* 4.181 - * Interface to the Xen ELF notes. 4.182 - */ 4.183 -#define ELFNOTE_NAME(_n_) ((const char*)(_n_) + sizeof(*(_n_))) 4.184 -#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3)) 4.185 -#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3)) 4.186 - 4.187 -static int is_xen_elfnote_section(const char *image, const Elf_Shdr *shdr) 4.188 -{ 4.189 - const Elf_Note *note; 4.190 - 4.191 - if ( shdr->sh_type != SHT_NOTE ) 4.192 - return 0; 4.193 - 4.194 - for ( note = (const Elf_Note *)(image + shdr->sh_offset); 4.195 - note < (const Elf_Note *)(image + shdr->sh_offset + shdr->sh_size); 4.196 - note = (const Elf_Note *)ELFNOTE_NEXT(note) ) 4.197 - { 4.198 - if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) ) 4.199 - return 1; 4.200 - } 4.201 - 4.202 - return 0; 4.203 -} 4.204 - 4.205 -static const Elf_Note *xen_elfnote_lookup( 4.206 - const struct domain_setup_info *dsi, int type) 4.207 -{ 4.208 - const Elf_Note *note; 4.209 - 4.210 - if ( !dsi->__elfnote_section ) 4.211 - return NULL; 4.212 - 4.213 - for ( note = (const Elf_Note *)dsi->__elfnote_section; 4.214 - note < (const Elf_Note *)dsi->__elfnote_section_end; 4.215 - note = (const Elf_Note *)ELFNOTE_NEXT(note) ) 4.216 - { 4.217 - if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) ) 4.218 - continue; 4.219 - 4.220 - if ( note->type == type ) 4.221 - return note; 4.222 - } 4.223 - 4.224 - return NULL; 4.225 -} 4.226 - 4.227 -const char *xen_elfnote_string(const struct domain_setup_info *dsi, int type) 4.228 -{ 4.229 - const Elf_Note *note; 4.230 - 4.231 - if ( !dsi->__elfnote_section ) 4.232 - return xen_guest_string(dsi, type); 4.233 - 4.234 - note = xen_elfnote_lookup(dsi, type); 4.235 - if ( note == NULL ) 4.236 - return NULL; 4.237 - 4.238 - return (const char *)ELFNOTE_DESC(note); 4.239 -} 4.240 - 4.241 -unsigned long long xen_elfnote_numeric(const struct domain_setup_info *dsi, 4.242 - int type, int *defined) 4.243 -{ 4.244 - const Elf_Note *note; 4.245 - 4.246 - *defined = 0; 4.247 - 4.248 - if ( !dsi->__elfnote_section ) 4.249 - return xen_guest_numeric(dsi, type, defined); 4.250 - 4.251 - note = xen_elfnote_lookup(dsi, type); 4.252 - if ( note == NULL ) 4.253 - { 4.254 - return 0; 4.255 - } 4.256 - 4.257 - switch ( note->descsz ) 4.258 - { 4.259 - case 4: 4.260 - *defined = 1; 4.261 - return *(const uint32_t*)ELFNOTE_DESC(note); 4.262 - case 8: 4.263 - *defined = 1; 4.264 - return *(const uint64_t*)ELFNOTE_DESC(note); 4.265 - default: 4.266 - xc_set_error(XC_INVALID_KERNEL, 4.267 - "elfnotes: unknown data size %#x for numeric type note %#x\n", 4.268 - note->descsz, type); 4.269 - return 0; 4.270 - } 4.271 -} 4.272 - 4.273 -static int parseelfimage(const char *image, 4.274 - unsigned long image_len, 4.275 - struct domain_setup_info *dsi) 4.276 -{ 4.277 - const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image; 4.278 - const Elf_Phdr *phdr; 4.279 - const Elf_Shdr *shdr; 4.280 - Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry; 4.281 - const char *shstrtab, *p; 4.282 - int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined; 4.283 - 4.284 - if ( !IS_ELF(*ehdr) ) 4.285 - { 4.286 - xc_set_error(XC_INVALID_KERNEL, 4.287 - "Kernel image does not have an ELF header."); 4.288 - return -EINVAL; 4.289 - } 4.290 - 4.291 - if (ehdr->e_machine != ELFMACHINE) 4.292 - { 4.293 - xc_set_error(XC_INVALID_KERNEL, 4.294 - "Kernel ELF architecture '%d' does not match Xen architecture '%d' (%s)", 4.295 - ehdr->e_machine, ELFMACHINE, ELFMACHINE_DESC); 4.296 - return -EINVAL; 4.297 - } 4.298 - if (ehdr->e_ident[EI_CLASS] != ELFCLASS) 4.299 - { 4.300 - xc_set_error(XC_INVALID_KERNEL, 4.301 - "Kernel ELF wordsize '%d' does not match Xen wordsize '%d' (%s)", 4.302 - ehdr->e_ident[EI_CLASS], ELFCLASS, ELFCLASS_DESC); 4.303 - return -EINVAL; 4.304 - } 4.305 - if (ehdr->e_ident[EI_DATA] != ELFDATA) 4.306 - { 4.307 - xc_set_error(XC_INVALID_KERNEL, 4.308 - "Kernel ELF endianness '%d' does not match Xen endianness '%d' (%s)", 4.309 - ehdr->e_ident[EI_DATA], ELFDATA, ELFDATA_DESC); 4.310 - return -EINVAL; 4.311 - } 4.312 - if (ehdr->e_type != ET_EXEC) 4.313 - { 4.314 - xc_set_error(XC_INVALID_KERNEL, 4.315 - "Kernel ELF type '%d' does not match Xen type '%d'", 4.316 - ehdr->e_type, ET_EXEC); 4.317 - return -EINVAL; 4.318 - } 4.319 - 4.320 - if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len ) 4.321 - { 4.322 - xc_set_error(XC_INVALID_KERNEL, 4.323 - "ELF program headers extend beyond end of image."); 4.324 - return -EINVAL; 4.325 - } 4.326 - 4.327 - if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len ) 4.328 - { 4.329 - xc_set_error(XC_INVALID_KERNEL, 4.330 - "ELF section headers extend beyond end of image."); 4.331 - return -EINVAL; 4.332 - } 4.333 - 4.334 - dsi->__elfnote_section = NULL; 4.335 - dsi->__xen_guest_string = NULL; 4.336 - 4.337 - /* Look for .notes segment containing at least one Xen note */ 4.338 - for ( h = 0; h < ehdr->e_shnum; h++ ) 4.339 - { 4.340 - shdr = (const Elf_Shdr *)( 4.341 - image + ehdr->e_shoff + (h*ehdr->e_shentsize)); 4.342 - if ( !is_xen_elfnote_section(image, shdr) ) 4.343 - continue; 4.344 - dsi->__elfnote_section = (const char *)image + shdr->sh_offset; 4.345 - dsi->__elfnote_section_end = 4.346 - (const char *)image + shdr->sh_offset + shdr->sh_size; 4.347 - break; 4.348 - } 4.349 - 4.350 - /* Fall back to looking for the special '__xen_guest' section. */ 4.351 - if ( dsi->__elfnote_section == NULL ) 4.352 - { 4.353 - /* Find the section-header strings table. */ 4.354 - if ( ehdr->e_shstrndx == SHN_UNDEF ) 4.355 - { 4.356 - xc_set_error(XC_INVALID_KERNEL, 4.357 - "ELF image has no section-header strings table."); 4.358 - return -EINVAL; 4.359 - } 4.360 - shdr = (const Elf_Shdr *)(image + ehdr->e_shoff + 4.361 - (ehdr->e_shstrndx*ehdr->e_shentsize)); 4.362 - shstrtab = image + shdr->sh_offset; 4.363 - 4.364 - for ( h = 0; h < ehdr->e_shnum; h++ ) 4.365 - { 4.366 - shdr = (const Elf_Shdr *)( 4.367 - image + ehdr->e_shoff + (h*ehdr->e_shentsize)); 4.368 - if ( is_xen_guest_section(shdr, shstrtab) ) 4.369 - { 4.370 - dsi->__xen_guest_string = 4.371 - (const char *)image + shdr->sh_offset; 4.372 - break; 4.373 - } 4.374 - } 4.375 - } 4.376 - 4.377 - /* Check the contents of the Xen notes or guest string. */ 4.378 - if ( dsi->__elfnote_section || dsi->__xen_guest_string ) 4.379 - { 4.380 - const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER); 4.381 - const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS); 4.382 - const char *xen_version = 4.383 - xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION); 4.384 - 4.385 - if ( ( loader == NULL || strncmp(loader, "generic", 7) ) && 4.386 - ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) ) 4.387 - { 4.388 - xc_set_error(XC_INVALID_KERNEL, 4.389 - "Will only load images built for the generic loader " 4.390 - "or Linux images"); 4.391 - return -EINVAL; 4.392 - } 4.393 - 4.394 - if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) ) 4.395 - { 4.396 - xc_set_error(XC_INVALID_KERNEL, 4.397 - "Will only load images built for Xen v3.0"); 4.398 - return -EINVAL; 4.399 - } 4.400 - } 4.401 - else 4.402 - { 4.403 -#if defined(__x86_64__) || defined(__i386__) 4.404 - xc_set_error(XC_INVALID_KERNEL, 4.405 - "Not a Xen-ELF image: " 4.406 - "No ELF notes or '__xen_guest' section found."); 4.407 - return -EINVAL; 4.408 -#endif 4.409 - } 4.410 - 4.411 - /* 4.412 - * A "bimodal" ELF note indicates the kernel will adjust to the current 4.413 - * paging mode, including handling extended cr3 syntax. If we have ELF 4.414 - * notes then PAE=yes implies that we must support the extended cr3 syntax. 4.415 - * Otherwise we need to find the [extended-cr3] syntax in the __xen_guest 4.416 - * string. We use strstr() to look for "bimodal" to allow guests to use 4.417 - * "yes,bimodal" or "no,bimodal" for compatibility reasons. 4.418 - */ 4.419 - 4.420 - dsi->pae_kernel = PAEKERN_no; 4.421 - if ( dsi->__elfnote_section ) 4.422 - { 4.423 - p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE); 4.424 - if ( p != NULL && strstr(p, "bimodal") != NULL ) 4.425 - dsi->pae_kernel = PAEKERN_bimodal; 4.426 - else if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 4.427 - dsi->pae_kernel = PAEKERN_extended_cr3; 4.428 - 4.429 - } 4.430 - else 4.431 - { 4.432 - p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE); 4.433 - if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 4.434 - { 4.435 - dsi->pae_kernel = PAEKERN_yes; 4.436 - if ( !strncmp(p+3, "[extended-cr3]", 14) ) 4.437 - dsi->pae_kernel = PAEKERN_extended_cr3; 4.438 - } 4.439 - } 4.440 - 4.441 - /* Initial guess for v_start is 0 if it is not explicitly defined. */ 4.442 - dsi->v_start = 4.443 - xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined); 4.444 - if ( !virt_base_defined ) 4.445 - dsi->v_start = 0; 4.446 - 4.447 - /* 4.448 - * If we are using the legacy __xen_guest section then elf_pa_off 4.449 - * defaults to v_start in order to maintain compatibility with 4.450 - * older hypervisors which set padd in the ELF header to 4.451 - * virt_base. 4.452 - * 4.453 - * If we are using the modern ELF notes interface then the default 4.454 - * is 0. 4.455 - */ 4.456 - dsi->elf_paddr_offset = xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, 4.457 - &elf_pa_off_defined); 4.458 - if ( !elf_pa_off_defined ) 4.459 - { 4.460 - if ( dsi->__elfnote_section ) 4.461 - dsi->elf_paddr_offset = 0; 4.462 - else 4.463 - dsi->elf_paddr_offset = dsi->v_start; 4.464 - } 4.465 - 4.466 - if ( elf_pa_off_defined && !virt_base_defined ) 4.467 - { 4.468 - xc_set_error(XC_INVALID_KERNEL, 4.469 - "Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF " 4.470 - " notes or __xen_guest section."); 4.471 - return -EINVAL; 4.472 - } 4.473 - 4.474 - for ( h = 0; h < ehdr->e_phnum; h++ ) 4.475 - { 4.476 - phdr = (const Elf_Phdr *)( 4.477 - image + ehdr->e_phoff + (h*ehdr->e_phentsize)); 4.478 - if ( !is_loadable_phdr(phdr) ) 4.479 - continue; 4.480 - vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start; 4.481 - if ( (vaddr + phdr->p_memsz) < vaddr ) 4.482 - { 4.483 - xc_set_error(XC_INVALID_KERNEL, 4.484 - "ELF program header %d is too large.", h); 4.485 - return -EINVAL; 4.486 - } 4.487 - 4.488 - if ( vaddr < kernstart ) 4.489 - kernstart = vaddr; 4.490 - if ( (vaddr + phdr->p_memsz) > kernend ) 4.491 - kernend = vaddr + phdr->p_memsz; 4.492 - } 4.493 - 4.494 - dsi->v_kernentry = ehdr->e_entry; 4.495 - 4.496 - virt_entry = 4.497 - xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined); 4.498 - if ( virt_entry_defined ) 4.499 - dsi->v_kernentry = virt_entry; 4.500 - 4.501 - if ( (kernstart > kernend) || 4.502 - (dsi->v_kernentry < kernstart) || 4.503 - (dsi->v_kernentry > kernend) || 4.504 - (dsi->v_start > kernstart) ) 4.505 - { 4.506 - xc_set_error(XC_INVALID_KERNEL, 4.507 - "ELF start or entries are out of bounds."); 4.508 - return -EINVAL; 4.509 - } 4.510 - 4.511 - p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB); 4.512 - if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 4.513 - dsi->load_symtab = 1; 4.514 - 4.515 - dsi->v_kernstart = kernstart; 4.516 - dsi->v_kernend = kernend; 4.517 - dsi->v_end = dsi->v_kernend; 4.518 - 4.519 - loadelfsymtab(image, 0, 0, NULL, dsi); 4.520 - 4.521 - return 0; 4.522 -} 4.523 - 4.524 -static int 4.525 -loadelfimage( 4.526 - const char *image, unsigned long elfsize, int xch, uint32_t dom, 4.527 - xen_pfn_t *parray, struct domain_setup_info *dsi) 4.528 -{ 4.529 - const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image; 4.530 - const Elf_Phdr *phdr; 4.531 - int h; 4.532 - 4.533 - char *va; 4.534 - unsigned long pa, done, chunksz; 4.535 - 4.536 - for ( h = 0; h < ehdr->e_phnum; h++ ) 4.537 - { 4.538 - phdr = (const Elf_Phdr *)( 4.539 - image + ehdr->e_phoff + (h*ehdr->e_phentsize)); 4.540 - if ( !is_loadable_phdr(phdr) ) 4.541 - continue; 4.542 - 4.543 - for ( done = 0; done < phdr->p_filesz; done += chunksz ) 4.544 - { 4.545 - pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset; 4.546 - va = xc_map_foreign_range( 4.547 - xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]); 4.548 - if ( va == NULL ) 4.549 - return -1; 4.550 - chunksz = phdr->p_filesz - done; 4.551 - if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) 4.552 - chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); 4.553 - memcpy(va + (pa & (PAGE_SIZE-1)), 4.554 - image + phdr->p_offset + done, chunksz); 4.555 - munmap(va, PAGE_SIZE); 4.556 - } 4.557 - 4.558 - for ( ; done < phdr->p_memsz; done += chunksz ) 4.559 - { 4.560 - pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset; 4.561 - va = xc_map_foreign_range( 4.562 - xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]); 4.563 - if ( va == NULL ) 4.564 - return -1; 4.565 - chunksz = phdr->p_memsz - done; 4.566 - if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) 4.567 - chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); 4.568 - memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz); 4.569 - munmap(va, PAGE_SIZE); 4.570 - } 4.571 - } 4.572 - 4.573 - loadelfsymtab(image, xch, dom, parray, dsi); 4.574 - 4.575 - return 0; 4.576 -} 4.577 - 4.578 -#define ELFROUND (ELFSIZE / 8) 4.579 - 4.580 -static int 4.581 -loadelfsymtab( 4.582 - const char *image, int xch, uint32_t dom, xen_pfn_t *parray, 4.583 - struct domain_setup_info *dsi) 4.584 -{ 4.585 - const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image; 4.586 - Elf_Ehdr *sym_ehdr; 4.587 - Elf_Shdr *shdr; 4.588 - unsigned long maxva, symva; 4.589 - char *p; 4.590 - int h, i; 4.591 - 4.592 - if ( !dsi->load_symtab ) 4.593 - return 0; 4.594 - 4.595 - p = malloc(sizeof(int) + sizeof(Elf_Ehdr) + 4.596 - ehdr->e_shnum * sizeof(Elf_Shdr)); 4.597 - if (p == NULL) 4.598 - return 0; 4.599 - 4.600 - maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1); 4.601 - symva = maxva; 4.602 - maxva += sizeof(int); 4.603 - dsi->symtab_addr = maxva; 4.604 - dsi->symtab_len = 0; 4.605 - maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr); 4.606 - maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); 4.607 - 4.608 - shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr)); 4.609 - memcpy(shdr, image + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr)); 4.610 - 4.611 - for ( h = 0; h < ehdr->e_shnum; h++ ) 4.612 - { 4.613 - if ( shdr[h].sh_type == SHT_STRTAB ) 4.614 - { 4.615 - /* Look for a strtab @i linked to symtab @h. */ 4.616 - for ( i = 0; i < ehdr->e_shnum; i++ ) 4.617 - if ( (shdr[i].sh_type == SHT_SYMTAB) && 4.618 - (shdr[i].sh_link == h) ) 4.619 - break; 4.620 - /* Skip symtab @h if we found no corresponding strtab @i. */ 4.621 - if ( i == ehdr->e_shnum ) 4.622 - { 4.623 - shdr[h].sh_offset = 0; 4.624 - continue; 4.625 - } 4.626 - } 4.627 - 4.628 - if ( (shdr[h].sh_type == SHT_STRTAB) || 4.629 - (shdr[h].sh_type == SHT_SYMTAB) ) 4.630 - { 4.631 - if ( parray != NULL ) 4.632 - xc_map_memcpy(maxva, image + shdr[h].sh_offset, 4.633 - shdr[h].sh_size, 4.634 - xch, dom, parray, dsi->v_start); 4.635 - 4.636 - /* Mangled to be based on ELF header location. */ 4.637 - shdr[h].sh_offset = maxva - dsi->symtab_addr; 4.638 - 4.639 - dsi->symtab_len += shdr[h].sh_size; 4.640 - maxva += shdr[h].sh_size; 4.641 - maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); 4.642 - } 4.643 - 4.644 - shdr[h].sh_name = 0; /* Name is NULL. */ 4.645 - } 4.646 - 4.647 - if ( dsi->symtab_len == 0 ) 4.648 - { 4.649 - dsi->symtab_addr = 0; 4.650 - goto out; 4.651 - } 4.652 - 4.653 - if ( parray != NULL ) 4.654 - { 4.655 - *(int *)p = maxva - dsi->symtab_addr; 4.656 - sym_ehdr = (Elf_Ehdr *)(p + sizeof(int)); 4.657 - memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr)); 4.658 - sym_ehdr->e_phoff = 0; 4.659 - sym_ehdr->e_shoff = sizeof(Elf_Ehdr); 4.660 - sym_ehdr->e_phentsize = 0; 4.661 - sym_ehdr->e_phnum = 0; 4.662 - sym_ehdr->e_shstrndx = SHN_UNDEF; 4.663 - 4.664 - /* Copy total length, crafted ELF header and section header table */ 4.665 - xc_map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) + 4.666 - ehdr->e_shnum * sizeof(Elf_Shdr), xch, dom, parray, 4.667 - dsi->v_start); 4.668 - } 4.669 - 4.670 - dsi->symtab_len = maxva - dsi->symtab_addr; 4.671 - dsi->v_end = round_pgup(maxva); 4.672 - 4.673 - out: 4.674 - free(p); 4.675 - 4.676 - return 0; 4.677 -} 4.678 - 4.679 -/* 4.680 - * Local variables: 4.681 - * mode: C 4.682 - * c-set-style: "BSD" 4.683 - * c-basic-offset: 4 4.684 - * tab-width: 4 4.685 - * indent-tabs-mode: nil 4.686 - * End: 4.687 - */
5.1 --- a/tools/libxc/xc_private.c Wed Feb 14 12:18:32 2007 -0800 5.2 +++ b/tools/libxc/xc_private.c Thu Feb 15 10:25:39 2007 +0000 5.3 @@ -377,26 +377,6 @@ int xc_clear_domain_page(int xc_handle, 5.4 return 0; 5.5 } 5.6 5.7 -void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size, 5.8 - int xch, uint32_t dom, xen_pfn_t *parray, 5.9 - unsigned long vstart) 5.10 -{ 5.11 - char *va; 5.12 - unsigned long chunksz, done, pa; 5.13 - 5.14 - for ( done = 0; done < size; done += chunksz ) 5.15 - { 5.16 - pa = dst + done - vstart; 5.17 - va = xc_map_foreign_range( 5.18 - xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]); 5.19 - chunksz = size - done; 5.20 - if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) 5.21 - chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); 5.22 - memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz); 5.23 - munmap(va, PAGE_SIZE); 5.24 - } 5.25 -} 5.26 - 5.27 int xc_domctl(int xc_handle, struct xen_domctl *domctl) 5.28 { 5.29 return do_domctl(xc_handle, domctl);
6.1 --- a/tools/libxc/xg_private.h Wed Feb 14 12:18:32 2007 -0800 6.2 +++ b/tools/libxc/xg_private.h Thu Feb 15 10:25:39 2007 +0000 6.3 @@ -139,92 +139,15 @@ typedef l4_pgentry_64_t l4_pgentry_t; 6.4 #define PAGE_SIZE_IA64 (1UL << PAGE_SHIFT_IA64) 6.5 #define PAGE_MASK_IA64 (~(PAGE_SIZE_IA64-1)) 6.6 6.7 -struct domain_setup_info 6.8 -{ 6.9 - uint64_t v_start; 6.10 - uint64_t v_end; 6.11 - uint64_t v_kernstart; 6.12 - uint64_t v_kernend; 6.13 - uint64_t v_kernentry; 6.14 - 6.15 - uint64_t elf_paddr_offset; 6.16 - 6.17 #define PAEKERN_no 0 6.18 #define PAEKERN_yes 1 6.19 #define PAEKERN_extended_cr3 2 6.20 #define PAEKERN_bimodal 3 6.21 - unsigned int pae_kernel; 6.22 - 6.23 - unsigned int load_symtab; 6.24 - unsigned long symtab_addr; 6.25 - unsigned long symtab_len; 6.26 - 6.27 - /* 6.28 - * Only one of __elfnote_* or __xen_guest_string will be 6.29 - * non-NULL. 6.30 - * 6.31 - * You should use the xen_elfnote_* accessors below in order to 6.32 - * pickup the correct one and retain backwards compatibility. 6.33 - */ 6.34 - const void *__elfnote_section, *__elfnote_section_end; 6.35 - const char *__xen_guest_string; 6.36 -}; 6.37 - 6.38 -typedef int (*parseimagefunc)(const char *image, unsigned long image_size, 6.39 - struct domain_setup_info *dsi); 6.40 -typedef int (*loadimagefunc)(const char *image, unsigned long image_size, 6.41 - int xch, 6.42 - uint32_t dom, xen_pfn_t *parray, 6.43 - struct domain_setup_info *dsi); 6.44 - 6.45 -/* 6.46 - * If an ELF note of the given type is found then the value contained 6.47 - * in the note is returned and *defined is set to non-zero. If no such 6.48 - * note is found then *defined is set to 0 and 0 is returned. 6.49 - */ 6.50 -extern unsigned long long xen_elfnote_numeric(const struct domain_setup_info *dsi, 6.51 - int type, int *defined); 6.52 - 6.53 -/* 6.54 - * If an ELF note of the given type is found then the string contained 6.55 - * in the value is returned, otherwise NULL is returned. 6.56 - */ 6.57 -extern const char * xen_elfnote_string(const struct domain_setup_info *dsi, 6.58 - int type); 6.59 - 6.60 -struct load_funcs 6.61 -{ 6.62 - parseimagefunc parseimage; 6.63 - loadimagefunc loadimage; 6.64 -}; 6.65 - 6.66 -#define mfn_mapper_queue_size 128 6.67 - 6.68 -typedef struct mfn_mapper { 6.69 - int xc_handle; 6.70 - int size; 6.71 - int prot; 6.72 - int error; 6.73 - int max_queue_size; 6.74 - void * addr; 6.75 - privcmd_mmap_t ioctl; 6.76 - 6.77 -} mfn_mapper_t; 6.78 6.79 int xc_copy_to_domain_page(int xc_handle, uint32_t domid, 6.80 unsigned long dst_pfn, const char *src_page); 6.81 6.82 -void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size, 6.83 - int xch, uint32_t dom, xen_pfn_t *parray, 6.84 - unsigned long vstart); 6.85 - 6.86 int pin_table(int xc_handle, unsigned int type, unsigned long mfn, 6.87 domid_t dom); 6.88 6.89 -/* image loading */ 6.90 -int probe_elf(const char *image, unsigned long image_size, 6.91 - struct load_funcs *funcs); 6.92 -int probe_bin(const char *image, unsigned long image_size, 6.93 - struct load_funcs *funcs); 6.94 - 6.95 #endif /* XG_PRIVATE_H */
7.1 --- a/xen/common/elf.c Wed Feb 14 12:18:32 2007 -0800 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,520 +0,0 @@ 7.4 -/****************************************************************************** 7.5 - * elf.c 7.6 - * 7.7 - * Generic Elf-loading routines. 7.8 - */ 7.9 - 7.10 -#include <xen/config.h> 7.11 -#include <xen/init.h> 7.12 -#include <xen/lib.h> 7.13 -#include <xen/mm.h> 7.14 -#include <xen/elf.h> 7.15 -#include <xen/sched.h> 7.16 -#include <xen/errno.h> 7.17 -#include <xen/inttypes.h> 7.18 - 7.19 -#include <public/elfnote.h> 7.20 - 7.21 -static void loadelfsymtab(struct domain_setup_info *dsi, int doload); 7.22 -static inline int is_loadable_phdr(const Elf_Phdr *phdr) 7.23 -{ 7.24 - return ((phdr->p_type == PT_LOAD) && 7.25 - ((phdr->p_flags & (PF_W|PF_X)) != 0)); 7.26 -} 7.27 - 7.28 -/* 7.29 - * Fallback for kernels containing only the legacy __xen_guest string 7.30 - * and no ELF notes. 7.31 - */ 7.32 -static int is_xen_guest_section(const Elf_Shdr *shdr, const char *shstrtab) 7.33 -{ 7.34 - return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0; 7.35 -} 7.36 - 7.37 -static const char *xen_guest_lookup(struct domain_setup_info *dsi, int type) 7.38 -{ 7.39 - const char *xenguest_fallbacks[] = { 7.40 - [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=", 7.41 - [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=", 7.42 - [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=", 7.43 - [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=", 7.44 - [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=", 7.45 - [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=", 7.46 - [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=", 7.47 - [XEN_ELFNOTE_LOADER] = "LOADER=", 7.48 - [XEN_ELFNOTE_PAE_MODE] = "PAE=", 7.49 - [XEN_ELFNOTE_FEATURES] = "FEATURES=", 7.50 - [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=", 7.51 - }; 7.52 - const char *fallback; 7.53 - const char *p; 7.54 - 7.55 - if ( !dsi->__xen_guest_string ) 7.56 - return NULL; 7.57 - 7.58 - if ( type > sizeof(xenguest_fallbacks) ) 7.59 - return NULL; 7.60 - 7.61 - if ( (fallback = xenguest_fallbacks[type]) == NULL ) 7.62 - return NULL; 7.63 - 7.64 - if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL ) 7.65 - return NULL; 7.66 - 7.67 - return p + strlen(fallback); 7.68 -} 7.69 - 7.70 -static const char *xen_guest_string(struct domain_setup_info *dsi, int type) 7.71 -{ 7.72 - const char *p = xen_guest_lookup(dsi, type); 7.73 - 7.74 - /* 7.75 - * We special case this since the __xen_guest_section treats the 7.76 - * mere precense of the BSD_SYMTAB string as true or false. 7.77 - */ 7.78 - if ( type == XEN_ELFNOTE_BSD_SYMTAB ) 7.79 - return p ? "yes" : "no"; 7.80 - 7.81 - return p; 7.82 -} 7.83 - 7.84 -static unsigned long long xen_guest_numeric(struct domain_setup_info *dsi, 7.85 - int type, int *defined) 7.86 -{ 7.87 - const char *p = xen_guest_lookup(dsi, type); 7.88 - unsigned long long value; 7.89 - 7.90 - if ( p == NULL ) 7.91 - return 0; 7.92 - 7.93 - value = simple_strtoull(p, NULL, 0); 7.94 - 7.95 - /* We special case this since __xen_guest_section contains a PFN 7.96 - * for this field not a virtual address. 7.97 - */ 7.98 - if (type == XEN_ELFNOTE_HYPERCALL_PAGE) 7.99 - value = dsi->v_start + (value<<PAGE_SHIFT); 7.100 - 7.101 - *defined = 1; 7.102 - return value; 7.103 -} 7.104 - 7.105 - 7.106 -static int is_xen_elfnote_section(const char *image, const Elf_Shdr *shdr) 7.107 -{ 7.108 - const Elf_Note *note; 7.109 - 7.110 - if ( shdr->sh_type != SHT_NOTE ) 7.111 - return 0; 7.112 - 7.113 - for ( note = (const Elf_Note *)(image + shdr->sh_offset); 7.114 - note < (const Elf_Note *)(image + shdr->sh_offset + shdr->sh_size); 7.115 - note = ELFNOTE_NEXT(note) ) 7.116 - { 7.117 - if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) ) 7.118 - return 1; 7.119 - } 7.120 - 7.121 - return 0; 7.122 -} 7.123 - 7.124 -static const Elf_Note *xen_elfnote_lookup( 7.125 - struct domain_setup_info *dsi, int type) 7.126 -{ 7.127 - const Elf_Note *note; 7.128 - 7.129 - if ( !dsi->__elfnote_section ) 7.130 - return NULL; 7.131 - 7.132 - for ( note = (const Elf_Note *)dsi->__elfnote_section; 7.133 - note < (const Elf_Note *)dsi->__elfnote_section_end; 7.134 - note = ELFNOTE_NEXT(note) ) 7.135 - { 7.136 - if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) ) 7.137 - continue; 7.138 - 7.139 - if ( note->type == type ) 7.140 - return note; 7.141 - } 7.142 - 7.143 - return NULL; 7.144 -} 7.145 - 7.146 -const char *xen_elfnote_string(struct domain_setup_info *dsi, int type) 7.147 -{ 7.148 - const Elf_Note *note; 7.149 - 7.150 - if ( !dsi->__elfnote_section ) 7.151 - return xen_guest_string(dsi, type); 7.152 - 7.153 - note = xen_elfnote_lookup(dsi, type); 7.154 - if ( note == NULL ) 7.155 - return NULL; 7.156 - 7.157 - return (const char *)ELFNOTE_DESC(note); 7.158 -} 7.159 - 7.160 -unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi, 7.161 - int type, int *defined) 7.162 -{ 7.163 - const Elf_Note *note; 7.164 - 7.165 - *defined = 0; 7.166 - 7.167 - if ( !dsi->__elfnote_section ) 7.168 - return xen_guest_numeric(dsi, type, defined); 7.169 - 7.170 - note = xen_elfnote_lookup(dsi, type); 7.171 - if ( note == NULL ) 7.172 - { 7.173 - return 0; 7.174 - } 7.175 - 7.176 - switch ( note->descsz ) 7.177 - { 7.178 - case 4: 7.179 - *defined = 1; 7.180 - return *(const uint32_t*)ELFNOTE_DESC(note); 7.181 - case 8: 7.182 - *defined = 1; 7.183 - return *(const uint64_t*)ELFNOTE_DESC(note); 7.184 - default: 7.185 - printk("ERROR: unknown data size %#x for numeric type note %#x\n", 7.186 - note->descsz, type); 7.187 - return 0; 7.188 - } 7.189 -} 7.190 - 7.191 -int parseelfimage(struct domain_setup_info *dsi) 7.192 -{ 7.193 - const Elf_Ehdr *ehdr = (const Elf_Ehdr *)dsi->image_addr; 7.194 - const Elf_Phdr *phdr; 7.195 - const Elf_Shdr *shdr; 7.196 - Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry; 7.197 - const char *shstrtab, *p; 7.198 - const char *image = (char *)dsi->image_addr; 7.199 - const unsigned long image_len = dsi->image_len; 7.200 - int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined; 7.201 - 7.202 - if ( !elf_sanity_check(ehdr) ) 7.203 - return -ENOSYS; 7.204 - 7.205 - if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len ) 7.206 - { 7.207 - printk("ELF program headers extend beyond end of image.\n"); 7.208 - return -EINVAL; 7.209 - } 7.210 - 7.211 - if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len ) 7.212 - { 7.213 - printk("ELF section headers extend beyond end of image.\n"); 7.214 - return -EINVAL; 7.215 - } 7.216 - 7.217 - dsi->__elfnote_section = NULL; 7.218 - dsi->__xen_guest_string = NULL; 7.219 - 7.220 - /* Look for .notes segment containing at least one Xen note */ 7.221 - for ( h = 0; h < ehdr->e_shnum; h++ ) 7.222 - { 7.223 - shdr = (const Elf_Shdr *)( 7.224 - image + ehdr->e_shoff + (h*ehdr->e_shentsize)); 7.225 - if ( !is_xen_elfnote_section(image, shdr) ) 7.226 - continue; 7.227 - dsi->__elfnote_section = (const char *)image + shdr->sh_offset; 7.228 - dsi->__elfnote_section_end = 7.229 - (const char *)image + shdr->sh_offset + shdr->sh_size; 7.230 - break; 7.231 - } 7.232 - 7.233 - /* Fall back to looking for the special '__xen_guest' section. */ 7.234 - if ( dsi->__elfnote_section == NULL ) 7.235 - { 7.236 - /* Find the section-header strings table. */ 7.237 - if ( ehdr->e_shstrndx == SHN_UNDEF ) 7.238 - { 7.239 - printk("ELF image has no section-header strings table.\n"); 7.240 - return -EINVAL; 7.241 - } 7.242 - shdr = (const Elf_Shdr *)(image + ehdr->e_shoff + 7.243 - (ehdr->e_shstrndx*ehdr->e_shentsize)); 7.244 - shstrtab = image + shdr->sh_offset; 7.245 - 7.246 - for ( h = 0; h < ehdr->e_shnum; h++ ) 7.247 - { 7.248 - shdr = (const Elf_Shdr *)( 7.249 - image + ehdr->e_shoff + (h*ehdr->e_shentsize)); 7.250 - if ( is_xen_guest_section(shdr, shstrtab) ) 7.251 - { 7.252 - dsi->__xen_guest_string = 7.253 - (const char *)image + shdr->sh_offset; 7.254 - break; 7.255 - } 7.256 - } 7.257 - } 7.258 - 7.259 - /* Check the contents of the Xen notes or guest string. */ 7.260 - if ( dsi->__elfnote_section || dsi->__xen_guest_string ) 7.261 - { 7.262 - const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER); 7.263 - const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS); 7.264 - const char *xen_version = 7.265 - xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION); 7.266 - 7.267 - if ( ( loader == NULL || strncmp(loader, "generic", 7) ) && 7.268 - ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) ) 7.269 - { 7.270 - printk("ERROR: Will only load images built for the generic " 7.271 - "loader or Linux images"); 7.272 - return -EINVAL; 7.273 - } 7.274 - 7.275 - if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) ) 7.276 - { 7.277 - printk("ERROR: Xen will only load images built for Xen v3.0\n"); 7.278 - } 7.279 - } 7.280 - else 7.281 - { 7.282 -#if defined(__x86_64__) || defined(__i386__) 7.283 - printk("ERROR: Not a Xen-ELF image: " 7.284 - "No ELF notes or '__xen_guest' section found.\n"); 7.285 - return -EINVAL; 7.286 -#endif 7.287 - } 7.288 - 7.289 - /* 7.290 - * A "bimodal" ELF note indicates the kernel will adjust to the 7.291 - * current paging mode, including handling extended cr3 syntax. 7.292 - * If we have ELF notes then PAE=yes implies that we must support 7.293 - * the extended cr3 syntax. Otherwise we need to find the 7.294 - * [extended-cr3] syntax in the __xen_guest string. 7.295 - */ 7.296 - dsi->pae_kernel = PAEKERN_no; 7.297 - if ( dsi->__elfnote_section ) 7.298 - { 7.299 - p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE); 7.300 - if ( p != NULL && strstr(p, "bimodal") != NULL ) 7.301 - dsi->pae_kernel = PAEKERN_bimodal; 7.302 - else if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 7.303 - dsi->pae_kernel = PAEKERN_extended_cr3; 7.304 - } 7.305 - else 7.306 - { 7.307 - p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE); 7.308 - if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 7.309 - { 7.310 - dsi->pae_kernel = PAEKERN_yes; 7.311 - if ( !strncmp(p+3, "[extended-cr3]", 14) ) 7.312 - dsi->pae_kernel = PAEKERN_extended_cr3; 7.313 - } 7.314 - } 7.315 - 7.316 - /* Initial guess for v_start is 0 if it is not explicitly defined. */ 7.317 - dsi->v_start = 7.318 - xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined); 7.319 - if ( !virt_base_defined ) 7.320 - dsi->v_start = 0; 7.321 - 7.322 - /* 7.323 - * If we are using the legacy __xen_guest section then elf_pa_off 7.324 - * defaults to v_start in order to maintain compatibility with 7.325 - * older hypervisors which set padd in the ELF header to 7.326 - * virt_base. 7.327 - * 7.328 - * If we are using the modern ELF notes interface then the default 7.329 - * is 0. 7.330 - */ 7.331 - dsi->elf_paddr_offset = xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, 7.332 - &elf_pa_off_defined); 7.333 - if ( !elf_pa_off_defined ) 7.334 - { 7.335 - if ( dsi->__elfnote_section ) 7.336 - dsi->elf_paddr_offset = 0; 7.337 - else 7.338 - dsi->elf_paddr_offset = dsi->v_start; 7.339 - } 7.340 - 7.341 - if ( elf_pa_off_defined && !virt_base_defined ) 7.342 - { 7.343 - printk("ERROR: Neither ELF_PADDR_OFFSET nor VIRT_BASE found in" 7.344 - " Xen ELF notes.\n"); 7.345 - return -EINVAL; 7.346 - } 7.347 - 7.348 - for ( h = 0; h < ehdr->e_phnum; h++ ) 7.349 - { 7.350 - phdr = (const Elf_Phdr *)( 7.351 - image + ehdr->e_phoff + (h*ehdr->e_phentsize)); 7.352 - if ( !is_loadable_phdr(phdr) ) 7.353 - continue; 7.354 - vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start; 7.355 - if ( (vaddr + phdr->p_memsz) < vaddr ) 7.356 - { 7.357 - printk("ERROR: ELF program header %d is too large.\n", h); 7.358 - return -EINVAL; 7.359 - } 7.360 - 7.361 - if ( vaddr < kernstart ) 7.362 - kernstart = vaddr; 7.363 - if ( (vaddr + phdr->p_memsz) > kernend ) 7.364 - kernend = vaddr + phdr->p_memsz; 7.365 - } 7.366 - 7.367 - dsi->v_kernentry = ehdr->e_entry; 7.368 - 7.369 - virt_entry = 7.370 - xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined); 7.371 - if ( virt_entry_defined ) 7.372 - dsi->v_kernentry = virt_entry; 7.373 - 7.374 - if ( (kernstart > kernend) || 7.375 - (dsi->v_kernentry < kernstart) || 7.376 - (dsi->v_kernentry > kernend) || 7.377 - (dsi->v_start > kernstart) ) 7.378 - { 7.379 - printk("ERROR: ELF start or entries are out of bounds.\n"); 7.380 - return -EINVAL; 7.381 - } 7.382 - 7.383 - p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB); 7.384 - if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 7.385 - dsi->load_symtab = 1; 7.386 - 7.387 - dsi->v_kernstart = kernstart; 7.388 - dsi->v_kernend = kernend; 7.389 - dsi->v_end = dsi->v_kernend; 7.390 - 7.391 - loadelfsymtab(dsi, 0); 7.392 - 7.393 - return 0; 7.394 -} 7.395 - 7.396 -int loadelfimage(struct domain_setup_info *dsi) 7.397 -{ 7.398 - char *image = (char *)dsi->image_addr; 7.399 - Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr; 7.400 - Elf_Phdr *phdr; 7.401 - unsigned long vaddr; 7.402 - int h; 7.403 - 7.404 - for ( h = 0; h < ehdr->e_phnum; h++ ) 7.405 - { 7.406 - phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize)); 7.407 - if ( !is_loadable_phdr(phdr) ) 7.408 - continue; 7.409 - vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start; 7.410 - if ( phdr->p_filesz != 0 ) 7.411 - memcpy((char *)vaddr, image + phdr->p_offset, phdr->p_filesz); 7.412 - if ( phdr->p_memsz > phdr->p_filesz ) 7.413 - memset((char *)vaddr + phdr->p_filesz, 0, 7.414 - phdr->p_memsz - phdr->p_filesz); 7.415 - } 7.416 - 7.417 - loadelfsymtab(dsi, 1); 7.418 - 7.419 - return 0; 7.420 -} 7.421 - 7.422 -#define ELFROUND (ELFSIZE / 8) 7.423 - 7.424 -static void loadelfsymtab(struct domain_setup_info *dsi, int doload) 7.425 -{ 7.426 - Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr, *sym_ehdr; 7.427 - Elf_Shdr *shdr; 7.428 - unsigned long maxva, symva; 7.429 - char *p, *image = (char *)dsi->image_addr; 7.430 - int h, i; 7.431 - 7.432 - if ( !dsi->load_symtab ) 7.433 - return; 7.434 - 7.435 - maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1); 7.436 - symva = maxva; 7.437 - maxva += sizeof(int); 7.438 - dsi->symtab_addr = maxva; 7.439 - dsi->symtab_len = 0; 7.440 - maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr); 7.441 - maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); 7.442 - if ( doload ) 7.443 - { 7.444 - p = (void *)symva; 7.445 - shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr)); 7.446 - memcpy(shdr, image + ehdr->e_shoff, ehdr->e_shnum*sizeof(Elf_Shdr)); 7.447 - } 7.448 - else 7.449 - { 7.450 - p = NULL; 7.451 - shdr = (Elf_Shdr *)(image + ehdr->e_shoff); 7.452 - } 7.453 - 7.454 - for ( h = 0; h < ehdr->e_shnum; h++ ) 7.455 - { 7.456 - if ( shdr[h].sh_type == SHT_STRTAB ) 7.457 - { 7.458 - /* Look for a strtab @i linked to symtab @h. */ 7.459 - for ( i = 0; i < ehdr->e_shnum; i++ ) 7.460 - if ( (shdr[i].sh_type == SHT_SYMTAB) && 7.461 - (shdr[i].sh_link == h) ) 7.462 - break; 7.463 - /* Skip symtab @h if we found no corresponding strtab @i. */ 7.464 - if ( i == ehdr->e_shnum ) 7.465 - { 7.466 - if (doload) { 7.467 - shdr[h].sh_offset = 0; 7.468 - } 7.469 - continue; 7.470 - } 7.471 - } 7.472 - 7.473 - if ( (shdr[h].sh_type == SHT_STRTAB) || 7.474 - (shdr[h].sh_type == SHT_SYMTAB) ) 7.475 - { 7.476 - if (doload) { 7.477 - memcpy((void *)maxva, image + shdr[h].sh_offset, 7.478 - shdr[h].sh_size); 7.479 - 7.480 - /* Mangled to be based on ELF header location. */ 7.481 - shdr[h].sh_offset = maxva - dsi->symtab_addr; 7.482 - 7.483 - } 7.484 - dsi->symtab_len += shdr[h].sh_size; 7.485 - maxva += shdr[h].sh_size; 7.486 - maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); 7.487 - } 7.488 - 7.489 - if ( doload ) 7.490 - shdr[h].sh_name = 0; /* Name is NULL. */ 7.491 - } 7.492 - 7.493 - if ( dsi->symtab_len == 0 ) 7.494 - { 7.495 - dsi->symtab_addr = 0; 7.496 - return; 7.497 - } 7.498 - 7.499 - if ( doload ) 7.500 - { 7.501 - *(int *)p = maxva - dsi->symtab_addr; 7.502 - sym_ehdr = (Elf_Ehdr *)(p + sizeof(int)); 7.503 - memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr)); 7.504 - sym_ehdr->e_phoff = 0; 7.505 - sym_ehdr->e_shoff = sizeof(Elf_Ehdr); 7.506 - sym_ehdr->e_phentsize = 0; 7.507 - sym_ehdr->e_phnum = 0; 7.508 - sym_ehdr->e_shstrndx = SHN_UNDEF; 7.509 - } 7.510 - 7.511 - dsi->symtab_len = maxva - dsi->symtab_addr; 7.512 - dsi->v_end = maxva; 7.513 -} 7.514 - 7.515 -/* 7.516 - * Local variables: 7.517 - * mode: C 7.518 - * c-set-style: "BSD" 7.519 - * c-basic-offset: 4 7.520 - * tab-width: 4 7.521 - * indent-tabs-mode: nil 7.522 - * End: 7.523 - */