static int alloc_magic_pages(struct xc_dom_image *dom) { struct ft_cxt devtree; void *guest_devtree; unsigned long shadow_mb; int rma_pages; int rc; /* Allocate special pages from the end of the RMA. */ rma_pages = 1 << (dom->realmodearea_log - PAGE_SHIFT); dom->shared_info_pfn = --rma_pages; dom->console_pfn = --rma_pages; dom->xenstore_pfn = --rma_pages; /* Gather shadow allocation info for the device tree. */ rc = xc_shadow_control(dom->guest_xc, dom->guest_domid, XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION, NULL, 0, &shadow_mb, 0, NULL); if (rc < 0 || shadow_mb == 0) { xc_dom_printf("Couldn't get shadow allocation size or it was 0.\n"); return rc; } /* Build device tree. */ rc = make_devtree(&devtree, dom, shadow_mb); if (rc < 0) { xc_dom_printf("Failed to create flattened device tree.\n"); return rc; } /* Find a spot for it. */ rc = xc_dom_alloc_segment(dom, &dom->devicetree_seg, "devtree", 0, devtree.bph->totalsize); if (rc) goto out; /* Copy the device tree into place. */ guest_devtree = xc_dom_seg_to_ptr(dom, &dom->devicetree_seg); if (!guest_devtree) { xc_dom_printf("Couldn't map guest memory for device tree.\n"); rc = -1; goto out; } memcpy(guest_devtree, devtree.bph, devtree.bph->totalsize); out: free_devtree(&devtree); return rc; }
int xc_dom_build_image(struct xc_dom_image *dom) { unsigned int page_size; xc_dom_printf("%s: called\n", __FUNCTION__); /* check for arch hooks */ if ( dom->arch_hooks == NULL ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n", __FUNCTION__); goto err; } page_size = XC_DOM_PAGE_SIZE(dom); /* load kernel */ if ( xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel", dom->kernel_seg.vstart, dom->kernel_seg.vend - dom->kernel_seg.vstart) != 0 ) goto err; if ( dom->kernel_loader->loader(dom) != 0 ) goto err; /* load ramdisk */ if ( dom->ramdisk_blob ) { size_t unziplen, ramdisklen; void *ramdiskmap; unziplen = xc_dom_check_gzip(dom->ramdisk_blob, dom->ramdisk_size); ramdisklen = unziplen ? unziplen : dom->ramdisk_size; if ( xc_dom_alloc_segment(dom, &dom->ramdisk_seg, "ramdisk", 0, ramdisklen) != 0 ) goto err; ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg); if ( unziplen ) { if ( xc_dom_do_gunzip(dom->ramdisk_blob, dom->ramdisk_size, ramdiskmap, ramdisklen) == -1 ) goto err; } else memcpy(ramdiskmap, dom->ramdisk_blob, dom->ramdisk_size); } /* allocate other pages */ if ( dom->arch_hooks->alloc_magic_pages(dom) != 0 ) goto err; if ( dom->arch_hooks->count_pgtables ) { dom->arch_hooks->count_pgtables(dom); if ( (dom->pgtables > 0) && (xc_dom_alloc_segment(dom, &dom->pgtables_seg, "page tables", 0, dom->pgtables * page_size) != 0) ) goto err; } if ( dom->alloc_bootstack ) dom->bootstack_pfn = xc_dom_alloc_page(dom, "boot stack"); xc_dom_printf("%-20s: virt_alloc_end : 0x%" PRIx64 "\n", __FUNCTION__, dom->virt_alloc_end); xc_dom_printf("%-20s: virt_pgtab_end : 0x%" PRIx64 "\n", __FUNCTION__, dom->virt_pgtab_end); return 0; err: return -1; }