debuggers.hg

view tools/libxc/xc_dom_core.c @ 21067:b4a1832a916f

Update Xen version to 4.0.0-rc6
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 09 18:18:05 2010 +0000 (2010-03-09)
parents 7a10f8513b3f
children 779c0ef9682c
line source
1 /*
2 * Xen domain builder -- core bits.
3 *
4 * The core code goes here:
5 * - allocate and release domain structs.
6 * - memory management functions.
7 * - misc helper functions.
8 *
9 * This code is licenced under the GPL.
10 * written 2006 by Gerd Hoffmann <kraxel@suse.de>.
11 *
12 */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <stdarg.h>
17 #include <inttypes.h>
18 #include <zlib.h>
20 #include "xg_private.h"
21 #include "xc_dom.h"
23 /* ------------------------------------------------------------------------ */
24 /* debugging */
26 FILE *xc_dom_logfile = NULL;
28 void xc_dom_loginit(void)
29 {
30 if ( xc_dom_logfile )
31 return;
32 xc_dom_logfile = fopen("/var/log/xen/domain-builder-ng.log", "a");
33 setvbuf(xc_dom_logfile, NULL, _IONBF, 0);
34 xc_dom_printf("### ----- xc domain builder logfile opened -----\n");
35 }
37 int xc_dom_printf(const char *fmt, ...)
38 {
39 va_list args;
40 char buf[1024];
41 int rc;
43 if ( !xc_dom_logfile )
44 return 0;
46 va_start(args, fmt);
47 rc = vsnprintf(buf, sizeof(buf), fmt, args);
48 va_end(args);
49 rc = fwrite(buf, rc, 1, xc_dom_logfile);
51 return rc;
52 }
54 int xc_dom_panic_func(const char *file, int line, xc_error_code err,
55 const char *fmt, ...)
56 {
57 va_list args;
58 FILE *fp = stderr;
59 int rc = 0;
60 char pos[256];
61 char msg[XC_MAX_ERROR_MSG_LEN];
63 if ( xc_dom_logfile )
64 fp = xc_dom_logfile;
66 snprintf(pos, sizeof(pos), "%s:%d: panic: ", file, line);
67 va_start(args, fmt);
68 vsnprintf(msg, sizeof(msg), fmt, args);
69 va_end(args);
70 xc_set_error(err, "%s", msg);
71 rc = fprintf(fp, "%s%s", pos, msg);
72 return rc;
73 }
75 static void print_mem(const char *name, size_t mem)
76 {
77 if ( mem > (32 * 1024 * 1024) )
78 xc_dom_printf("%-24s : %zd MB\n", name, mem / (1024 * 1024));
79 else if ( mem > (32 * 1024) )
80 xc_dom_printf("%-24s : %zd kB\n", name, mem / 1024);
81 else
82 xc_dom_printf("%-24s : %zd bytes\n", name, mem);
83 }
85 void xc_dom_log_memory_footprint(struct xc_dom_image *dom)
86 {
87 xc_dom_printf("domain builder memory footprint\n");
88 xc_dom_printf(" allocated\n");
89 print_mem(" malloc", dom->alloc_malloc);
90 print_mem(" anon mmap", dom->alloc_mem_map);
91 xc_dom_printf(" mapped\n");
92 print_mem(" file mmap", dom->alloc_file_map);
93 print_mem(" domU mmap", dom->alloc_domU_map);
94 }
96 /* ------------------------------------------------------------------------ */
97 /* simple memory pool */
99 void *xc_dom_malloc(struct xc_dom_image *dom, size_t size)
100 {
101 struct xc_dom_mem *block;
103 block = malloc(sizeof(*block) + size);
104 if ( block == NULL )
105 return NULL;
106 memset(block, 0, sizeof(*block) + size);
107 block->next = dom->memblocks;
108 dom->memblocks = block;
109 dom->alloc_malloc += sizeof(*block) + size;
110 if ( size > (100 * 1024) )
111 print_mem(__FUNCTION__, size);
112 return block->memory;
113 }
115 void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size)
116 {
117 struct xc_dom_mem *block;
119 block = malloc(sizeof(*block));
120 if ( block == NULL )
121 return NULL;
122 memset(block, 0, sizeof(*block));
123 block->mmap_len = size;
124 block->mmap_ptr = mmap(NULL, block->mmap_len,
125 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
126 -1, 0);
127 if ( block->mmap_ptr == MAP_FAILED )
128 {
129 free(block);
130 return NULL;
131 }
132 block->next = dom->memblocks;
133 dom->memblocks = block;
134 dom->alloc_malloc += sizeof(*block);
135 dom->alloc_mem_map += block->mmap_len;
136 if ( size > (100 * 1024) )
137 print_mem(__FUNCTION__, size);
138 return block->mmap_ptr;
139 }
141 void *xc_dom_malloc_filemap(struct xc_dom_image *dom,
142 const char *filename, size_t * size)
143 {
144 struct xc_dom_mem *block = NULL;
145 int fd = -1;
147 fd = open(filename, O_RDONLY);
148 if ( fd == -1 )
149 goto err;
151 lseek(fd, 0, SEEK_SET);
152 *size = lseek(fd, 0, SEEK_END);
154 block = malloc(sizeof(*block));
155 if ( block == NULL )
156 goto err;
157 memset(block, 0, sizeof(*block));
158 block->mmap_len = *size;
159 block->mmap_ptr = mmap(NULL, block->mmap_len, PROT_READ,
160 MAP_SHARED, fd, 0);
161 if ( block->mmap_ptr == MAP_FAILED )
162 goto err;
163 block->next = dom->memblocks;
164 dom->memblocks = block;
165 dom->alloc_malloc += sizeof(*block);
166 dom->alloc_file_map += block->mmap_len;
167 close(fd);
168 if ( *size > (100 * 1024) )
169 print_mem(__FUNCTION__, *size);
170 return block->mmap_ptr;
172 err:
173 if ( fd != -1 )
174 close(fd);
175 if ( block != NULL )
176 free(block);
177 return NULL;
178 }
180 static void xc_dom_free_all(struct xc_dom_image *dom)
181 {
182 struct xc_dom_mem *block;
184 while ( (block = dom->memblocks) != NULL )
185 {
186 dom->memblocks = block->next;
187 if ( block->mmap_ptr )
188 munmap(block->mmap_ptr, block->mmap_len);
189 free(block);
190 }
191 }
193 char *xc_dom_strdup(struct xc_dom_image *dom, const char *str)
194 {
195 size_t len = strlen(str) + 1;
196 char *nstr = xc_dom_malloc(dom, len);
198 if ( nstr == NULL )
199 return NULL;
200 memcpy(nstr, str, len);
201 return nstr;
202 }
204 /* ------------------------------------------------------------------------ */
205 /* read files, copy memory blocks, with transparent gunzip */
207 size_t xc_dom_check_gzip(void *blob, size_t ziplen)
208 {
209 unsigned char *gzlen;
210 size_t unziplen;
212 if ( strncmp(blob, "\037\213", 2) )
213 /* not gzipped */
214 return 0;
216 gzlen = blob + ziplen - 4;
217 unziplen = gzlen[3] << 24 | gzlen[2] << 16 | gzlen[1] << 8 | gzlen[0];
218 if ( (unziplen < 0) || (unziplen > (1024*1024*1024)) ) /* 1GB limit */
219 {
220 xc_dom_printf
221 ("%s: size (zip %zd, unzip %zd) looks insane, skip gunzip\n",
222 __FUNCTION__, ziplen, unziplen);
223 return 0;
224 }
226 return unziplen + 16;
227 }
229 int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen)
230 {
231 z_stream zStream;
232 int rc;
234 memset(&zStream, 0, sizeof(zStream));
235 zStream.next_in = src;
236 zStream.avail_in = srclen;
237 zStream.next_out = dst;
238 zStream.avail_out = dstlen;
239 rc = inflateInit2(&zStream, (MAX_WBITS + 32)); /* +32 means "handle gzip" */
240 if ( rc != Z_OK )
241 {
242 xc_dom_panic(XC_INTERNAL_ERROR,
243 "%s: inflateInit2 failed (rc=%d)\n", __FUNCTION__, rc);
244 return -1;
245 }
246 rc = inflate(&zStream, Z_FINISH);
247 inflateEnd(&zStream);
248 if ( rc != Z_STREAM_END )
249 {
250 xc_dom_panic(XC_INTERNAL_ERROR,
251 "%s: inflate failed (rc=%d)\n", __FUNCTION__, rc);
252 return -1;
253 }
255 xc_dom_printf("%s: unzip ok, 0x%zx -> 0x%zx\n",
256 __FUNCTION__, srclen, dstlen);
257 return 0;
258 }
260 int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size)
261 {
262 void *unzip;
263 size_t unziplen;
265 unziplen = xc_dom_check_gzip(*blob, *size);
266 if ( unziplen == 0 )
267 return 0;
269 unzip = xc_dom_malloc(dom, unziplen);
270 if ( unzip == NULL )
271 return -1;
273 if ( xc_dom_do_gunzip(*blob, *size, unzip, unziplen) == -1 )
274 return -1;
276 *blob = unzip;
277 *size = unziplen;
278 return 0;
279 }
281 /* ------------------------------------------------------------------------ */
282 /* domain memory */
284 void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn,
285 xen_pfn_t count)
286 {
287 struct xc_dom_phys *phys;
288 unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom);
289 char *mode = "unset";
291 if ( pfn > dom->total_pages || /* multiple checks to avoid overflows */
292 count > dom->total_pages ||
293 pfn > dom->total_pages - count )
294 {
295 xc_dom_printf("%s: pfn out of range (0x%" PRIpfn " > 0x%" PRIpfn ")\n",
296 __FUNCTION__, pfn, dom->total_pages);
297 return NULL;
298 }
300 /* already allocated? */
301 for ( phys = dom->phys_pages; phys != NULL; phys = phys->next )
302 {
303 if ( pfn >= (phys->first + phys->count) )
304 continue;
305 if ( count )
306 {
307 /* size given: must be completely within the already allocated block */
308 if ( (pfn + count) <= phys->first )
309 continue;
310 if ( (pfn < phys->first) ||
311 ((pfn + count) > (phys->first + phys->count)) )
312 {
313 xc_dom_printf("%s: request overlaps allocated block"
314 " (req 0x%" PRIpfn "+0x%" PRIpfn ","
315 " blk 0x%" PRIpfn "+0x%" PRIpfn ")\n",
316 __FUNCTION__, pfn, count, phys->first,
317 phys->count);
318 return NULL;
319 }
320 }
321 else
322 {
323 /* no size given: block must be allocated already,
324 just hand out a pointer to it */
325 if ( pfn < phys->first )
326 continue;
327 }
328 return phys->ptr + ((pfn - phys->first) << page_shift);
329 }
331 /* allocating is allowed with size specified only */
332 if ( count == 0 )
333 {
334 xc_dom_printf("%s: no block found, no size given,"
335 " can't malloc (pfn 0x%" PRIpfn ")\n",
336 __FUNCTION__, pfn);
337 return NULL;
338 }
340 /* not found, no overlap => allocate */
341 phys = xc_dom_malloc(dom, sizeof(*phys));
342 if ( phys == NULL )
343 return NULL;
344 memset(phys, 0, sizeof(*phys));
345 phys->first = pfn;
346 phys->count = count;
348 if ( dom->guest_domid )
349 {
350 mode = "domU mapping";
351 phys->ptr = xc_dom_boot_domU_map(dom, phys->first, phys->count);
352 if ( phys->ptr == NULL )
353 return NULL;
354 dom->alloc_domU_map += phys->count << page_shift;
355 }
356 else
357 {
358 int err;
360 mode = "anonymous memory";
361 phys->ptr = mmap(NULL, phys->count << page_shift,
362 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
363 -1, 0);
364 if ( phys->ptr == MAP_FAILED )
365 {
366 err = errno;
367 xc_dom_panic(XC_OUT_OF_MEMORY,
368 "%s: oom: can't allocate 0x%" PRIpfn " pages"
369 " [mmap, errno=%i (%s)]\n",
370 __FUNCTION__, count, err, strerror(err));
371 return NULL;
372 }
373 dom->alloc_mem_map += phys->count << page_shift;
374 }
376 #if 1
377 xc_dom_printf("%s: %s: pfn 0x%" PRIpfn "+0x%" PRIpfn " at %p\n",
378 __FUNCTION__, mode, phys->first, phys->count, phys->ptr);
379 #endif
380 phys->next = dom->phys_pages;
381 dom->phys_pages = phys;
382 return phys->ptr;
383 }
385 int xc_dom_alloc_segment(struct xc_dom_image *dom,
386 struct xc_dom_seg *seg, char *name,
387 xen_vaddr_t start, xen_vaddr_t size)
388 {
389 unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
390 xen_pfn_t pages = (size + page_size - 1) / page_size;
391 void *ptr;
393 if ( start == 0 )
394 start = dom->virt_alloc_end;
396 if ( start & (page_size - 1) )
397 {
398 xc_dom_panic(XC_INTERNAL_ERROR,
399 "%s: segment start isn't page aligned (0x%" PRIx64 ")\n",
400 __FUNCTION__, start);
401 return -1;
402 }
403 if ( start < dom->virt_alloc_end )
404 {
405 xc_dom_panic(XC_INTERNAL_ERROR,
406 "%s: segment start too low (0x%" PRIx64 " < 0x%" PRIx64
407 ")\n", __FUNCTION__, start, dom->virt_alloc_end);
408 return -1;
409 }
411 seg->vstart = start;
412 seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size;
414 if ( pages > dom->total_pages || /* double test avoids overflow probs */
415 pages > dom->total_pages - seg->pfn)
416 {
417 xc_dom_panic(XC_OUT_OF_MEMORY,
418 "%s: segment %s too large (0x%"PRIpfn" > "
419 "0x%"PRIpfn" - 0x%"PRIpfn" pages)\n",
420 __FUNCTION__, name, pages, dom->total_pages, seg->pfn);
421 return -1;
422 }
424 seg->vend = start + pages * page_size;
425 dom->virt_alloc_end = seg->vend;
426 if (dom->allocate)
427 dom->allocate(dom, dom->virt_alloc_end);
429 xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " -> 0x%" PRIx64
430 " (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)\n",
431 __FUNCTION__, name, seg->vstart, seg->vend, seg->pfn, pages);
433 /* map and clear pages */
434 ptr = xc_dom_seg_to_ptr(dom, seg);
435 if ( ptr == NULL )
436 return -1;
437 memset(ptr, 0, pages * page_size);
439 return 0;
440 }
442 int xc_dom_alloc_page(struct xc_dom_image *dom, char *name)
443 {
444 unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
445 xen_vaddr_t start;
446 xen_pfn_t pfn;
448 start = dom->virt_alloc_end;
449 dom->virt_alloc_end += page_size;
450 if (dom->allocate)
451 dom->allocate(dom, dom->virt_alloc_end);
452 pfn = (start - dom->parms.virt_base) / page_size;
454 xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")\n",
455 __FUNCTION__, name, start, pfn);
456 return pfn;
457 }
459 void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn)
460 {
461 unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom);
462 struct xc_dom_phys *phys, *prev = NULL;
464 for ( phys = dom->phys_pages; phys != NULL; phys = phys->next )
465 {
466 if ( (pfn >= phys->first) && (pfn < (phys->first + phys->count)) )
467 break;
468 prev = phys;
469 }
470 if ( !phys )
471 {
472 xc_dom_printf("%s: Huh? no mapping with pfn 0x%" PRIpfn "\n",
473 __FUNCTION__, pfn);
474 return;
475 }
477 munmap(phys->ptr, phys->count << page_shift);
478 if ( prev )
479 prev->next = phys->next;
480 else
481 dom->phys_pages = phys->next;
482 }
484 void xc_dom_unmap_all(struct xc_dom_image *dom)
485 {
486 while ( dom->phys_pages )
487 xc_dom_unmap_one(dom, dom->phys_pages->first);
488 }
490 /* ------------------------------------------------------------------------ */
491 /* pluggable kernel loaders */
493 static struct xc_dom_loader *first_loader = NULL;
494 static struct xc_dom_arch *first_hook = NULL;
496 void xc_dom_register_loader(struct xc_dom_loader *loader)
497 {
498 loader->next = first_loader;
499 first_loader = loader;
500 }
502 static struct xc_dom_loader *xc_dom_find_loader(struct xc_dom_image *dom)
503 {
504 struct xc_dom_loader *loader = first_loader;
506 while ( loader != NULL )
507 {
508 xc_dom_printf("%s: trying %s loader ... ", __FUNCTION__, loader->name);
509 if ( loader->probe(dom) == 0 )
510 {
511 xc_dom_printf("OK\n");
512 return loader;
513 }
514 xc_dom_printf("failed\n");
515 loader = loader->next;
516 }
517 xc_dom_panic(XC_INVALID_KERNEL, "%s: no loader found\n", __FUNCTION__);
518 return NULL;
519 }
521 void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks)
522 {
523 hooks->next = first_hook;
524 first_hook = hooks;
525 }
527 struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type)
528 {
529 struct xc_dom_arch *hooks = first_hook;
531 while ( hooks != NULL )
532 {
533 if ( !strcmp(hooks->guest_type, guest_type))
534 return hooks;
535 hooks = hooks->next;
536 }
537 xc_dom_panic(XC_INVALID_KERNEL,
538 "%s: not found (type %s)\n", __FUNCTION__, guest_type);
539 return NULL;
540 }
542 /* ------------------------------------------------------------------------ */
543 /* public interface */
545 void xc_dom_release(struct xc_dom_image *dom)
546 {
547 xc_dom_printf("%s: called\n", __FUNCTION__);
548 if ( dom->phys_pages )
549 xc_dom_unmap_all(dom);
550 xc_dom_free_all(dom);
551 free(dom);
552 }
554 struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char *features)
555 {
556 struct xc_dom_image *dom;
558 xc_dom_printf("%s: cmdline=\"%s\", features=\"%s\"\n",
559 __FUNCTION__, cmdline, features);
560 dom = malloc(sizeof(*dom));
561 if ( !dom )
562 goto err;
564 memset(dom, 0, sizeof(*dom));
565 if ( cmdline )
566 dom->cmdline = xc_dom_strdup(dom, cmdline);
567 if ( features )
568 elf_xen_parse_features(features, dom->f_requested, NULL);
570 dom->parms.virt_base = UNSET_ADDR;
571 dom->parms.virt_entry = UNSET_ADDR;
572 dom->parms.virt_hypercall = UNSET_ADDR;
573 dom->parms.virt_hv_start_low = UNSET_ADDR;
574 dom->parms.elf_paddr_offset = UNSET_ADDR;
576 dom->alloc_malloc += sizeof(*dom);
577 return dom;
579 err:
580 if ( dom )
581 xc_dom_release(dom);
582 return NULL;
583 }
585 int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename)
586 {
587 xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename);
588 dom->kernel_blob = xc_dom_malloc_filemap(dom, filename, &dom->kernel_size);
589 if ( dom->kernel_blob == NULL )
590 return -1;
591 return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size);
592 }
594 int xc_dom_ramdisk_file(struct xc_dom_image *dom, const char *filename)
595 {
596 xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename);
597 dom->ramdisk_blob =
598 xc_dom_malloc_filemap(dom, filename, &dom->ramdisk_size);
599 if ( dom->ramdisk_blob == NULL )
600 return -1;
601 // return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size);
602 return 0;
603 }
605 int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, size_t memsize)
606 {
607 xc_dom_printf("%s: called\n", __FUNCTION__);
608 dom->kernel_blob = (void *)mem;
609 dom->kernel_size = memsize;
610 return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size);
611 }
613 int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem,
614 size_t memsize)
615 {
616 xc_dom_printf("%s: called\n", __FUNCTION__);
617 dom->ramdisk_blob = (void *)mem;
618 dom->ramdisk_size = memsize;
619 // return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size);
620 return 0;
621 }
623 int xc_dom_parse_image(struct xc_dom_image *dom)
624 {
625 int i;
627 xc_dom_printf("%s: called\n", __FUNCTION__);
629 /* parse kernel image */
630 dom->kernel_loader = xc_dom_find_loader(dom);
631 if ( dom->kernel_loader == NULL )
632 goto err;
633 if ( dom->kernel_loader->parser(dom) != 0 )
634 goto err;
635 if ( dom->guest_type == NULL )
636 {
637 xc_dom_panic(XC_INTERNAL_ERROR,
638 "%s: guest_type not set\n", __FUNCTION__);
639 goto err;
640 }
642 /* check features */
643 for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
644 {
645 dom->f_active[i] |= dom->f_requested[i]; /* cmd line */
646 dom->f_active[i] |= dom->parms.f_required[i]; /* kernel */
647 if ( (dom->f_active[i] & dom->parms.f_supported[i]) !=
648 dom->f_active[i] )
649 {
650 xc_dom_panic(XC_INVALID_PARAM,
651 "%s: unsupported feature requested\n", __FUNCTION__);
652 goto err;
653 }
654 }
655 return 0;
657 err:
658 return -1;
659 }
661 int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb)
662 {
663 unsigned int page_shift;
664 xen_pfn_t nr_pages;
666 dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type);
667 if ( dom->arch_hooks == NULL )
668 {
669 xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n",
670 __FUNCTION__);
671 return -1;
672 }
674 page_shift = XC_DOM_PAGE_SHIFT(dom);
675 nr_pages = mem_mb << (20 - page_shift);
677 xc_dom_printf("%s: mem %d MB, pages 0x%" PRIpfn " pages, %dk each\n",
678 __FUNCTION__, mem_mb, nr_pages, 1 << (page_shift-10));
679 dom->total_pages = nr_pages;
681 xc_dom_printf("%s: 0x%" PRIpfn " pages\n",
682 __FUNCTION__, dom->total_pages);
684 return 0;
685 }
687 int xc_dom_update_guest_p2m(struct xc_dom_image *dom)
688 {
689 uint32_t *p2m_32;
690 uint64_t *p2m_64;
691 xen_pfn_t i;
693 if ( !dom->p2m_guest )
694 return 0;
696 switch ( dom->arch_hooks->sizeof_pfn )
697 {
698 case 4:
699 xc_dom_printf("%s: dst 32bit, pages 0x%" PRIpfn " \n",
700 __FUNCTION__, dom->total_pages);
701 p2m_32 = dom->p2m_guest;
702 for ( i = 0; i < dom->total_pages; i++ )
703 if ( dom->p2m_host[i] != INVALID_P2M_ENTRY )
704 p2m_32[i] = dom->p2m_host[i];
705 else
706 p2m_32[i] = (uint32_t) - 1;
707 break;
708 case 8:
709 xc_dom_printf("%s: dst 64bit, pages 0x%" PRIpfn " \n",
710 __FUNCTION__, dom->total_pages);
711 p2m_64 = dom->p2m_guest;
712 for ( i = 0; i < dom->total_pages; i++ )
713 if ( dom->p2m_host[i] != INVALID_P2M_ENTRY )
714 p2m_64[i] = dom->p2m_host[i];
715 else
716 p2m_64[i] = (uint64_t) - 1;
717 break;
718 default:
719 xc_dom_panic(XC_INTERNAL_ERROR,
720 "sizeof_pfn is invalid (is %d, can be 4 or 8)",
721 dom->arch_hooks->sizeof_pfn);
722 return -1;
723 }
724 return 0;
725 }
727 int xc_dom_build_image(struct xc_dom_image *dom)
728 {
729 unsigned int page_size;
731 xc_dom_printf("%s: called\n", __FUNCTION__);
733 /* check for arch hooks */
734 if ( dom->arch_hooks == NULL )
735 {
736 xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n",
737 __FUNCTION__);
738 goto err;
739 }
740 page_size = XC_DOM_PAGE_SIZE(dom);
742 /* load kernel */
743 if ( xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel",
744 dom->kernel_seg.vstart,
745 dom->kernel_seg.vend -
746 dom->kernel_seg.vstart) != 0 )
747 goto err;
748 if ( dom->kernel_loader->loader(dom) != 0 )
749 goto err;
751 /* load ramdisk */
752 if ( dom->ramdisk_blob )
753 {
754 size_t unziplen, ramdisklen;
755 void *ramdiskmap;
757 unziplen = xc_dom_check_gzip(dom->ramdisk_blob, dom->ramdisk_size);
758 ramdisklen = unziplen ? unziplen : dom->ramdisk_size;
759 if ( xc_dom_alloc_segment(dom, &dom->ramdisk_seg, "ramdisk", 0,
760 ramdisklen) != 0 )
761 goto err;
762 ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg);
763 if ( unziplen )
764 {
765 if ( xc_dom_do_gunzip(dom->ramdisk_blob, dom->ramdisk_size,
766 ramdiskmap, ramdisklen) == -1 )
767 goto err;
768 }
769 else
770 memcpy(ramdiskmap, dom->ramdisk_blob, dom->ramdisk_size);
771 }
773 /* allocate other pages */
774 if ( dom->arch_hooks->alloc_magic_pages(dom) != 0 )
775 goto err;
776 if ( dom->arch_hooks->count_pgtables )
777 {
778 dom->arch_hooks->count_pgtables(dom);
779 if ( (dom->pgtables > 0) &&
780 (xc_dom_alloc_segment(dom, &dom->pgtables_seg, "page tables", 0,
781 dom->pgtables * page_size) != 0) )
782 goto err;
783 }
784 if ( dom->alloc_bootstack )
785 dom->bootstack_pfn = xc_dom_alloc_page(dom, "boot stack");
786 xc_dom_printf("%-20s: virt_alloc_end : 0x%" PRIx64 "\n",
787 __FUNCTION__, dom->virt_alloc_end);
788 xc_dom_printf("%-20s: virt_pgtab_end : 0x%" PRIx64 "\n",
789 __FUNCTION__, dom->virt_pgtab_end);
790 return 0;
792 err:
793 return -1;
794 }
796 /*
797 * Local variables:
798 * mode: C
799 * c-set-style: "BSD"
800 * c-basic-offset: 4
801 * tab-width: 4
802 * indent-tabs-mode: nil
803 * End:
804 */