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;
}
Beispiel #2
0
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;
}