Exemple #1
0
static int alloc_magic_pages(struct xc_dom_image *dom)
{
    int rc, i;
    xen_pfn_t p2m[NR_MAGIC_PAGES];

    DOMPRINTF_CALLED(dom->xch);

    for (i = 0; i < NR_MAGIC_PAGES; i++)
        p2m[i] = dom->rambase_pfn + dom->total_pages + i;

    rc = xc_domain_populate_physmap_exact(
            dom->xch, dom->guest_domid, NR_MAGIC_PAGES,
            0, 0, p2m);
    if ( rc < 0 )
        return rc;

    dom->console_pfn = dom->rambase_pfn + dom->total_pages + CONSOLE_PFN_OFFSET;
    dom->xenstore_pfn = dom->rambase_pfn + dom->total_pages + XENSTORE_PFN_OFFSET;

    xc_clear_domain_page(dom->xch, dom->guest_domid, dom->console_pfn);
    xc_clear_domain_page(dom->xch, dom->guest_domid, dom->xenstore_pfn);
    xc_set_hvm_param(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_PFN,
            dom->console_pfn);
    xc_set_hvm_param(dom->xch, dom->guest_domid, HVM_PARAM_STORE_PFN,
            dom->xenstore_pfn);
    /* allocated by toolstack */
    xc_set_hvm_param(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_EVTCHN,
            dom->console_evtchn);
    xc_set_hvm_param(dom->xch, dom->guest_domid, HVM_PARAM_STORE_EVTCHN,
            dom->xenstore_evtchn);

    return 0;
}
Exemple #2
0
static int vcpu_arm64(struct xc_dom_image *dom, void *ptr)
{
    vcpu_guest_context_t *ctxt = ptr;

    DOMPRINTF_CALLED(dom->xch);
    /* clear everything */
    memset(ctxt, 0, sizeof(*ctxt));

    ctxt->user_regs.pc64 = dom->parms.virt_entry;

    /* Linux boot protocol. See linux.Documentation/arm64/booting.txt. */
    ctxt->user_regs.x0 = dom->devicetree_blob ?
        dom->devicetree_seg.vstart : 0xffffffff;
    ctxt->user_regs.x1 = 0;
    ctxt->user_regs.x2 = 0;
    ctxt->user_regs.x3 = 0;

    DOMPRINTF("DTB %"PRIx64, ctxt->user_regs.x0);

    ctxt->sctlr = SCTLR_GUEST_INIT;

    ctxt->ttbr0 = 0;
    ctxt->ttbr1 = 0;
    ctxt->ttbcr = 0; /* Defined Reset Value */

    ctxt->user_regs.cpsr = PSR_GUEST64_INIT;

    ctxt->flags = VGCF_online;

    DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx64,
           ctxt->user_regs.cpsr, ctxt->user_regs.pc64);

    return 0;
}
Exemple #3
0
int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, size_t memsize)
{
    DOMPRINTF_CALLED(dom->xch);
    dom->kernel_blob = (void *)mem;
    dom->kernel_size = memsize;
    return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size);
}
Exemple #4
0
int xc_dom_devicetree_mem(struct xc_dom_image *dom, const void *mem,
                          size_t memsize)
{
    DOMPRINTF_CALLED(dom->xch);
    dom->devicetree_blob = (void *)mem;
    dom->devicetree_size = memsize;
    return 0;
}
Exemple #5
0
void xc_dom_release(struct xc_dom_image *dom)
{
    DOMPRINTF_CALLED(dom->xch);
    if ( dom->phys_pages )
        xc_dom_unmap_all(dom);
    xc_dom_free_all(dom);
    free(dom);
}
Exemple #6
0
int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem,
                       size_t memsize)
{
    DOMPRINTF_CALLED(dom->xch);
    dom->ramdisk_blob = (void *)mem;
    dom->ramdisk_size = memsize;
//    return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size);
    return 0;
}
Exemple #7
0
static int xc_dom_parse_zimage32_kernel(struct xc_dom_image *dom)
{
    uint32_t *zimage;
    uint32_t start, entry_addr;
    uint64_t v_start, v_end;
    uint64_t rambase = dom->rambase_pfn << XC_PAGE_SHIFT;

    DOMPRINTF_CALLED(dom->xch);

    zimage = (uint32_t *)dom->kernel_blob;

    /* Do not load kernel at the very first RAM address */
    v_start = rambase + 0x8000;

    if ( dom->kernel_size > UINT64_MAX - v_start )
    {
        DOMPRINTF("%s: kernel is too large\n", __FUNCTION__);
        return -EINVAL;
    }

    v_end = v_start + dom->kernel_size;

    /*
     * If start is invalid then the guest will start at some invalid
     * address and crash, but this happens in guest context so doesn't
     * concern us here.
     */
    start = zimage[ZIMAGE32_START_OFFSET/4];

    if (start == 0)
        entry_addr = v_start;
    else
        entry_addr = start;

    /* find kernel segment */
    dom->kernel_seg.vstart = v_start;
    dom->kernel_seg.vend   = v_end;

    dom->parms.virt_entry = entry_addr;
    dom->parms.virt_base = rambase;

    dom->guest_type = "xen-3.0-armv7l";
    DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
              __FUNCTION__, dom->guest_type,
              dom->kernel_seg.vstart, dom->kernel_seg.vend);
    return 0;
}
Exemple #8
0
int xc_dom_boot_mem_init(struct xc_dom_image *dom)
{
    long rc;

    DOMPRINTF_CALLED(dom->xch);

    rc = arch_setup_meminit(dom);
    if ( rc != 0 )
    {
        xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
                     "%s: can't allocate low memory for domain",
                     __FUNCTION__);
        return rc;
    }

    return 0;
}
Exemple #9
0
int xc_dom_parse_image(struct xc_dom_image *dom)
{
    int i;

    DOMPRINTF_CALLED(dom->xch);

    /* parse kernel image */
    dom->kernel_loader = xc_dom_find_loader(dom);
    if ( dom->kernel_loader == NULL )
        goto err;
    if ( dom->kernel_loader->parser(dom) != 0 )
        goto err;
    if ( dom->guest_type == NULL )
    {
        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                     "%s: guest_type not set", __FUNCTION__);
        goto err;
    }

    if ( dom->pvh_enabled )
    {
        const char *pvh_features = "writable_descriptor_tables|"
                                   "auto_translated_physmap|"
                                   "supervisor_mode_kernel|"
                                   "hvm_callback_vector";
        elf_xen_parse_features(pvh_features, dom->f_requested, NULL);
    }

    /* check features */
    for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
    {
        dom->f_active[i] |= dom->f_requested[i]; /* cmd line */
        dom->f_active[i] |= dom->parms.f_required[i]; /* kernel   */
        if ( (dom->f_active[i] & dom->parms.f_supported[i]) !=
             dom->f_active[i] )
        {
            xc_dom_panic(dom->xch, XC_INVALID_PARAM,
                         "%s: unsupported feature requested", __FUNCTION__);
            goto err;
        }
    }
    return 0;

 err:
    return -1;
}
Exemple #10
0
static int xc_dom_parse_zimage64_kernel(struct xc_dom_image *dom)
{
    struct zimage64_hdr *zimage;
    uint64_t v_start, v_end;
    uint64_t rambase = dom->rambase_pfn << XC_PAGE_SHIFT;

    DOMPRINTF_CALLED(dom->xch);

    zimage = dom->kernel_blob;

    if ( zimage->text_offset > UINT64_MAX - rambase )
    {
        DOMPRINTF("%s: kernel text offset is too large\n", __FUNCTION__);
        return -EINVAL;
    }

    v_start = rambase + zimage->text_offset;

    if ( dom->kernel_size > UINT64_MAX - v_start )
    {
        DOMPRINTF("%s: kernel is too large\n", __FUNCTION__);
        return -EINVAL;
    }

    v_end = v_start + dom->kernel_size;

    dom->kernel_seg.vstart = v_start;
    dom->kernel_seg.vend   = v_end;

    /* Call the kernel at offset 0 */
    dom->parms.virt_entry = v_start;
    dom->parms.virt_base = rambase;

    dom->guest_type = "xen-3.0-aarch64";
    DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
              __FUNCTION__, dom->guest_type,
              dom->kernel_seg.vstart, dom->kernel_seg.vend);

    return 0;
}
static int xc_dom_parse_zimage_kernel(struct xc_dom_image *dom)
{
    uint32_t *zimage;
    uint32_t start, entry_addr;
    uint64_t v_start, v_end;
    uint64_t rambase = GUEST_RAM_BASE;

    DOMPRINTF_CALLED(dom->xch);

    zimage = (uint32_t *)dom->kernel_blob;

    dom->rambase_pfn = rambase >> XC_PAGE_SHIFT;

    /* Do not load kernel at the very first RAM address */
    v_start = rambase + 0x8000;
    v_end = v_start + dom->kernel_size;

    start = zimage[ZIMAGE_START_OFFSET/4];

    if (start == 0)
        entry_addr = v_start;
    else
        entry_addr = start;

    /* find kernel segment */
    dom->kernel_seg.vstart = v_start;
    dom->kernel_seg.vend   = v_end;

    dom->parms.virt_entry = entry_addr;
    dom->parms.virt_base = rambase;

    dom->guest_type = "xen-3.0-armv7l";
    DOMPRINTF("%s: %s: RAM starts at %"PRI_xen_pfn,
              __FUNCTION__, dom->guest_type, dom->rambase_pfn);
    DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
              __FUNCTION__, dom->guest_type,
              dom->kernel_seg.vstart, dom->kernel_seg.vend);
    return 0;
}
static int xc_dom_load_zimage_kernel(struct xc_dom_image *dom)
{
    void *dst;

    DOMPRINTF_CALLED(dom->xch);

    dst = xc_dom_seg_to_ptr(dom, &dom->kernel_seg);
    if ( dst == NULL )
    {
        DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &dom->kernel_seg) => NULL",
                  __func__);
        return -1;
    }

    DOMPRINTF("%s: kernel sed %#"PRIx64"-%#"PRIx64,
              __func__, dom->kernel_seg.vstart, dom->kernel_seg.vend);
    DOMPRINTF("%s: copy %zd bytes from blob %p to dst %p",
              __func__, dom->kernel_size, dom->kernel_blob, dst);

    memcpy(dst, dom->kernel_blob, dom->kernel_size);

    return 0;
}
Exemple #13
0
static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
{
    vcpu_guest_context_t *ctxt = ptr;

    DOMPRINTF_CALLED(dom->xch);

    /* clear everything */
    memset(ctxt, 0, sizeof(*ctxt));

    ctxt->user_regs.pc32 = dom->parms.virt_entry;

    /* Linux boot protocol. See linux.Documentation/arm/Booting. */
    ctxt->user_regs.r0_usr = 0; /* SBZ */
    /* Machine ID: We use DTB therefore no machine id */
    ctxt->user_regs.r1_usr = 0xffffffff;
    /* ATAGS/DTB: We currently require that the guest kernel to be
     * using CONFIG_ARM_APPENDED_DTB. Ensure that r2 does not look
     * like a valid pointer to a set of ATAGS or a DTB.
     */
    ctxt->user_regs.r2_usr = dom->devicetree_blob ?
        dom->devicetree_seg.vstart : 0xffffffff;

    ctxt->sctlr = SCTLR_GUEST_INIT;

    ctxt->ttbr0 = 0;
    ctxt->ttbr1 = 0;
    ctxt->ttbcr = 0; /* Defined Reset Value */

    ctxt->user_regs.cpsr = PSR_GUEST32_INIT;

    ctxt->flags = VGCF_online;

    DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32,
           ctxt->user_regs.cpsr, ctxt->user_regs.pc32);

    return 0;
}
Exemple #14
0
static int start_info_arm(struct xc_dom_image *dom)
{
    DOMPRINTF_CALLED(dom->xch);
    return 0;
}
Exemple #15
0
int xc_dom_boot_image(struct xc_dom_image *dom)
{
    DECLARE_HYPERCALL_BUFFER(vcpu_guest_context_any_t, ctxt);
    xc_dominfo_t info;
    int rc;

    ctxt = xc_hypercall_buffer_alloc(dom->xch, ctxt, sizeof(*ctxt));
    if ( ctxt == NULL )
        return -1;

    DOMPRINTF_CALLED(dom->xch);

    /* misc stuff*/
    if ( (rc = arch_setup_bootearly(dom)) != 0 )
        return rc;

    /* collect some info */
    rc = xc_domain_getinfo(dom->xch, dom->guest_domid, 1, &info);
    if ( rc < 0 )
    {
        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                     "%s: getdomaininfo failed (rc=%d)", __FUNCTION__, rc);
        return rc;
    }
    if ( rc == 0 || info.domid != dom->guest_domid )
    {
        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                     "%s: Huh? No domains found (nr_domains=%d) "
                     "or domid mismatch (%d != %d)", __FUNCTION__,
                     rc, info.domid, dom->guest_domid);
        return -1;
    }
    dom->shared_info_mfn = info.shared_info_frame;

    /* sanity checks */
    if ( !xc_dom_compat_check(dom) )
        return -1;

    /* initial mm setup */
    if ( (rc = xc_dom_update_guest_p2m(dom)) != 0 )
        return rc;
    if ( dom->arch_hooks->setup_pgtables )
        if ( (rc = dom->arch_hooks->setup_pgtables(dom)) != 0 )
            return rc;

    if ( (rc = clear_page(dom, dom->console_pfn)) != 0 )
        return rc;
    if ( (rc = clear_page(dom, dom->xenstore_pfn)) != 0 )
        return rc;

    /* start info page */
    if ( dom->arch_hooks->start_info )
        dom->arch_hooks->start_info(dom);

    /* hypercall page */
    if ( (rc = setup_hypercall_page(dom)) != 0 )
        return rc;
    xc_dom_log_memory_footprint(dom);

    /* misc x86 stuff */
    if ( (rc = arch_setup_bootlate(dom)) != 0 )
        return rc;

    /* let the vm run */
    memset(ctxt, 0, sizeof(*ctxt));
    if ( (rc = dom->arch_hooks->vcpu(dom, ctxt)) != 0 )
        return rc;
    xc_dom_unmap_all(dom);
    rc = launch_vm(dom->xch, dom->guest_domid, ctxt);

    xc_hypercall_buffer_free(dom->xch, ctxt);
    return rc;
}
Exemple #16
0
static int setup_pgtables_arm(struct xc_dom_image *dom)
{
    DOMPRINTF_CALLED(dom->xch);
    return 0;
}
Exemple #17
0
static int shared_info_arm(struct xc_dom_image *dom, void *ptr)
{
    DOMPRINTF_CALLED(dom->xch);
    return 0;
}