Пример #1
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;
}
Пример #2
0
void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size)
{
    struct xc_dom_mem *block;

    block = malloc(sizeof(*block));
    if ( block == NULL )
    {
        DOMPRINTF("%s: allocation failed", __FUNCTION__);
        return NULL;
    }
    memset(block, 0, sizeof(*block));
    block->mmap_len = size;
    block->mmap_ptr = mmap(NULL, block->mmap_len,
                           PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
                           -1, 0);
    if ( block->mmap_ptr == MAP_FAILED )
    {
        DOMPRINTF("%s: mmap failed", __FUNCTION__);
        free(block);
        return NULL;
    }
    block->next = dom->memblocks;
    dom->memblocks = block;
    dom->alloc_malloc += sizeof(*block);
    dom->alloc_mem_map += block->mmap_len;
    if ( size > (100 * 1024) )
        print_mem(dom, __FUNCTION__, size);
    return block->mmap_ptr;
}
Пример #3
0
static void print_mem(struct xc_dom_image *dom, const char *name, size_t mem)
{
    if ( mem > (32 * 1024 * 1024) )
        DOMPRINTF("%-24s : %zd MB", name, mem / (1024 * 1024));
    else if ( mem > (32 * 1024) )
        DOMPRINTF("%-24s : %zd kB", name, mem / 1024);
    else
        DOMPRINTF("%-24s : %zd bytes", name, mem);
}
Пример #4
0
void xc_dom_log_memory_footprint(struct xc_dom_image *dom)
{
    DOMPRINTF("domain builder memory footprint");
    DOMPRINTF("   allocated");
    print_mem(dom, "      malloc", dom->alloc_malloc);
    print_mem(dom, "      anon mmap", dom->alloc_mem_map);
    DOMPRINTF("   mapped");
    print_mem(dom, "      file mmap", dom->alloc_file_map);
    print_mem(dom, "      domU mmap", dom->alloc_domU_map);
}
Пример #5
0
int xc_dom_alloc_segment(struct xc_dom_image *dom,
                         struct xc_dom_seg *seg, char *name,
                         xen_vaddr_t start, xen_vaddr_t size)
{
    unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
    xen_pfn_t pages;
    void *ptr;

    if ( start && xc_dom_alloc_pad(dom, start) )
        return -1;

    pages = (size + page_size - 1) / page_size;
    start = dom->virt_alloc_end;

    seg->pfn = dom->pfn_alloc_end;
    seg->pages = pages;

    if ( xc_dom_chk_alloc_pages(dom, name, pages) )
        return -1;

    /* map and clear pages */
    ptr = xc_dom_seg_to_ptr(dom, seg);
    if ( ptr == NULL )
        return -1;
    memset(ptr, 0, pages * page_size);

    seg->vstart = start;
    seg->vend = dom->virt_alloc_end;

    DOMPRINTF("%-20s:   %-12s : 0x%" PRIx64 " -> 0x%" PRIx64
              "  (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)",
              __FUNCTION__, name, seg->vstart, seg->vend, seg->pfn, pages);

    return 0;
}
Пример #6
0
static int xc_try_lzo1x_decode(
    struct xc_dom_image *dom, void **blob, size_t *size)
{
    DOMPRINTF("%s: LZO1x decompress support unavailable\n",
                  __FUNCTION__);
    return -1;
}
Пример #7
0
static int xc_try_bzip2_decode(
    struct xc_dom_image *dom, void **blob, size_t *size)
{
    DOMPRINTF("%s: BZIP2 decompress support unavailable",
              __FUNCTION__);
    return -1;
}
Пример #8
0
int xc_dom_compat_check(struct xc_dom_image *dom)
{
    xen_capabilities_info_t xen_caps;
    char *item, *ptr;
    int match, found = 0;

    strncpy(xen_caps, dom->xen_caps, XEN_CAPABILITIES_INFO_LEN - 1);
    xen_caps[XEN_CAPABILITIES_INFO_LEN - 1] = '\0';

    for ( item = strtok_r(xen_caps, " ", &ptr);
          item != NULL ; item = strtok_r(NULL, " ", &ptr) )
    {
        match = !strcmp(dom->guest_type, item);
        DOMPRINTF("%s: supported guest type: %s%s", __FUNCTION__,
                  item, match ? " <= matches" : "");
        if ( match )
            found++;
    }
    if ( !found )
        xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
                     "%s: guest type %s not supported by xen kernel, sorry",
                     __FUNCTION__, dom->guest_type);

    return found;
}
Пример #9
0
void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn)
{
    unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom);
    struct xc_dom_phys *phys, *prev = NULL;

    for ( phys = dom->phys_pages; phys != NULL; phys = phys->next )
    {
        if ( (pfn >= phys->first) && (pfn < (phys->first + phys->count)) )
            break;
        prev = phys;
    }
    if ( !phys )
    {
        DOMPRINTF("%s: Huh? no mapping with pfn 0x%" PRIpfn "",
                  __FUNCTION__, pfn);
        return;
    }

    munmap(phys->ptr, phys->count << page_shift);
    if ( prev )
        prev->next = phys->next;
    else
        dom->phys_pages = phys->next;

    xc_domain_cacheflush(dom->xch, dom->guest_domid, phys->first, phys->count);
}
Пример #10
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;
}
Пример #11
0
int xc_dom_alloc_segment(struct xc_dom_image *dom,
                         struct xc_dom_seg *seg, char *name,
                         xen_vaddr_t start, xen_vaddr_t size)
{
    unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
    xen_pfn_t pages = (size + page_size - 1) / page_size;
    xen_pfn_t pfn;
    void *ptr;

    if ( start == 0 )
        start = dom->virt_alloc_end;

    if ( start & (page_size - 1) )
    {
        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                     "%s: segment start isn't page aligned (0x%" PRIx64 ")",
                     __FUNCTION__, start);
        return -1;
    }
    if ( start < dom->virt_alloc_end )
    {
        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                     "%s: segment start too low (0x%" PRIx64 " < 0x%" PRIx64
                     ")", __FUNCTION__, start, dom->virt_alloc_end);
        return -1;
    }

    seg->vstart = start;
    pfn = (seg->vstart - dom->parms.virt_base) / page_size;
    seg->pfn = pfn + dom->rambase_pfn;

    if ( pages > dom->total_pages || /* multiple test avoids overflow probs */
         pfn > dom->total_pages ||
         pages > dom->total_pages - pfn)
    {
        xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
                     "%s: segment %s too large (0x%"PRIpfn" > "
                     "0x%"PRIpfn" - 0x%"PRIpfn" pages)",
                     __FUNCTION__, name, pages, dom->total_pages, pfn);
        return -1;
    }

    seg->vend = start + pages * page_size;
    dom->virt_alloc_end = seg->vend;
    if (dom->allocate)
        dom->allocate(dom, dom->virt_alloc_end);

    DOMPRINTF("%-20s:   %-12s : 0x%" PRIx64 " -> 0x%" PRIx64
              "  (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)",
              __FUNCTION__, name, seg->vstart, seg->vend, seg->pfn, pages);

    /* map and clear pages */
    ptr = xc_dom_seg_to_ptr(dom, seg);
    if ( ptr == NULL )
        return -1;
    memset(ptr, 0, pages * page_size);

    return 0;
}
Пример #12
0
int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename)
{
    DOMPRINTF("%s: filename=\"%s\"", __FUNCTION__, filename);
    dom->kernel_blob = xc_dom_malloc_filemap(dom, filename, &dom->kernel_size,
                                             dom->max_kernel_size);
    if ( dom->kernel_blob == NULL )
        return -1;
    return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size);
}
Пример #13
0
static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
{
    struct xen_bin_image_table *image_info;
    char *image = dom->kernel_blob;
    char *dest;
    size_t image_size = dom->kernel_size;
    size_t dest_size;
    uint32_t start_addr;
    uint32_t load_end_addr;
    uint32_t bss_end_addr;
    uint32_t skip, text_size, bss_size;

    image_info = find_table(dom);
    if ( !image_info )
        return -EINVAL;

    start_addr = image_info->header_addr - ((char *)image_info - image);
    load_end_addr = image_info->load_end_addr ?: start_addr + image_size;
    bss_end_addr = image_info->bss_end_addr ?: load_end_addr;

    /* It's possible that we need to skip the first part of the image */
    skip = image_info->load_addr - start_addr;
    text_size = load_end_addr - image_info->load_addr;
    bss_size = bss_end_addr - load_end_addr;

    DOMPRINTF("%s: calculated sizes", __FUNCTION__);
    DOMPRINTF("  skip:      0x%" PRIx32 "", skip);
    DOMPRINTF("  text_size: 0x%" PRIx32 "", text_size);
    DOMPRINTF("  bss_size:  0x%" PRIx32 "", bss_size);

    dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart, &dest_size);
    if ( dest == NULL )
    {
        DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart)"
                  " => NULL", __FUNCTION__);
        return -EINVAL;
    }

    if ( dest_size < text_size ||
         dest_size - text_size < bss_size )
    {
        DOMPRINTF("%s: mapped region is too small for image", __FUNCTION__);
        return -EINVAL;
    }

    if ( image_size < skip ||
         image_size - skip < text_size )
    {
        DOMPRINTF("%s: image is too small for declared text size",
                  __FUNCTION__);
        return -EINVAL;
    }

    memcpy(dest, image + skip, text_size);
    memset(dest + text_size, 0, bss_size);

    return 0;
}
Пример #14
0
static struct xc_dom_loader *xc_dom_find_loader(struct xc_dom_image *dom)
{
    struct xc_dom_loader *loader = first_loader;

    while ( loader != NULL )
    {
        DOMPRINTF("%s: trying %s loader ... ", __FUNCTION__, loader->name);
        if ( loader->probe(dom) == 0 )
        {
            DOMPRINTF("loader probe OK");
            return loader;
        }
        DOMPRINTF("loader probe failed");
        loader = loader->next;
    }
    xc_dom_panic(dom->xch,
                 XC_INVALID_KERNEL, "%s: no loader found", __FUNCTION__);
    return NULL;
}
Пример #15
0
static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
                                  struct elf_binary *elf, bool load)
{
    struct elf_binary syms;
    ELF_HANDLE_DECL(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
    xen_vaddr_t symtab, maxaddr;
    elf_ptrval hdr;
    size_t size;
    unsigned h, count, type, i, tables = 0;
    unsigned long *strtab_referenced = NULL;

    if ( elf_swap(elf) )
    {
        DOMPRINTF("%s: non-native byte order, bsd symtab not supported",
                  __FUNCTION__);
        return 0;
    }

    size = elf->bsd_symtab_pend - elf->bsd_symtab_pstart;

    if ( load )
    {
        char *hdr_ptr;
        size_t allow_size;

        if ( !dom->bsd_symtab_start )
            return 0;
        hdr_ptr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start, &allow_size);
        if ( hdr_ptr == NULL )
        {
            DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom,dom->bsd_symtab_start"
                      " => NULL", __FUNCTION__);
            return -1;
        }
        elf->caller_xdest_base = hdr_ptr;
        elf->caller_xdest_size = allow_size;
        hdr = ELF_REALPTR2PTRVAL(hdr_ptr);
        elf_store_val(elf, unsigned, hdr, size - sizeof(unsigned));
    }
    else
    {
Пример #16
0
static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
{
    struct elf_binary *elf;
    int rc;

    rc = check_elf_kernel(dom, 1);
    if ( rc != 0 )
        return rc;

    elf = xc_dom_malloc(dom, sizeof(*elf));
    dom->private_loader = elf;
    rc = elf_init(elf, dom->kernel_blob, dom->kernel_size);
    xc_elf_set_logfile(dom->xch, elf, 1);
    if ( rc != 0 )
    {
        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: corrupted ELF image",
                     __FUNCTION__);
        return rc;
    }

    /* Find the section-header strings table. */
    if ( elf->sec_strtab == NULL )
    {
        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
                     " has no shstrtab", __FUNCTION__);
        return -EINVAL;
    }

    /* parse binary and get xen meta info */
    elf_parse_binary(elf);
    if ( (rc = elf_xen_parse(elf, &dom->parms)) != 0 )
        return rc;

    if ( elf_xen_feature_get(XENFEAT_dom0, dom->parms.f_required) )
    {
        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Kernel does not"
                     " support unprivileged (DomU) operation", __FUNCTION__);
        return -EINVAL;
    }

    /* find kernel segment */
    dom->kernel_seg.vstart = dom->parms.virt_kstart;
    dom->kernel_seg.vend   = dom->parms.virt_kend;

    if ( dom->parms.bsd_symtab )
        xc_dom_load_elf_symtab(dom, elf, 0);

    dom->guest_type = xc_dom_guest_type(dom, elf);
    DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
              __FUNCTION__, dom->guest_type,
              dom->kernel_seg.vstart, dom->kernel_seg.vend);
    return 0;
}
Пример #17
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;
}
Пример #18
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;
}
Пример #19
0
static int xc_try_lzma_decode(
    struct xc_dom_image *dom, void **blob, size_t *size)
{
    lzma_stream stream = LZMA_STREAM_INIT;

    if ( lzma_alone_decoder(&stream, LZMA_BLOCK_SIZE) != LZMA_OK )
    {
        DOMPRINTF("LZMA: Failed to init decoder");
        return -1;
    }

    return _xc_try_lzma_decode(dom, blob, size, &stream, "LZMA");
}
Пример #20
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;
}
Пример #21
0
void *xc_dom_malloc(struct xc_dom_image *dom, size_t size)
{
    struct xc_dom_mem *block;

    if ( size > SIZE_MAX - sizeof(*block) )
    {
        DOMPRINTF("%s: unreasonable allocation size", __FUNCTION__);
        return NULL;
    }
    block = malloc(sizeof(*block) + size);
    if ( block == NULL )
    {
        DOMPRINTF("%s: allocation failed", __FUNCTION__);
        return NULL;
    }
    memset(block, 0, sizeof(*block) + size);
    block->next = dom->memblocks;
    dom->memblocks = block;
    dom->alloc_malloc += sizeof(*block) + size;
    if ( size > (100 * 1024) )
        print_mem(dom, __FUNCTION__, size);
    return block->memory;
}
Пример #22
0
xen_pfn_t xc_dom_alloc_page(struct xc_dom_image *dom, char *name)
{
    xen_vaddr_t start;
    xen_pfn_t pfn;

    start = dom->virt_alloc_end;
    pfn = dom->pfn_alloc_end - dom->rambase_pfn;

    if ( xc_dom_chk_alloc_pages(dom, name, 1) )
        return INVALID_PFN;

    DOMPRINTF("%-20s:   %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")",
              __FUNCTION__, name, start, pfn);
    return pfn;
}
Пример #23
0
int xc_dom_devicetree_file(struct xc_dom_image *dom, const char *filename)
{
#if defined (__arm__) || defined(__aarch64__)
    DOMPRINTF("%s: filename=\"%s\"", __FUNCTION__, filename);
    dom->devicetree_blob =
        xc_dom_malloc_filemap(dom, filename, &dom->devicetree_size,
                              dom->max_devicetree_size);

    if ( dom->devicetree_blob == NULL )
        return -1;
    return 0;
#else
    errno = -EINVAL;
    return -1;
#endif
}
Пример #24
0
int xc_dom_alloc_page(struct xc_dom_image *dom, char *name)
{
    unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
    xen_vaddr_t start;
    xen_pfn_t pfn;

    start = dom->virt_alloc_end;
    dom->virt_alloc_end += page_size;
    if (dom->allocate)
        dom->allocate(dom, dom->virt_alloc_end);
    pfn = (start - dom->parms.virt_base) / page_size;

    DOMPRINTF("%-20s:   %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")",
              __FUNCTION__, name, start, pfn);
    return pfn;
}
Пример #25
0
static int clear_page(struct xc_dom_image *dom, xen_pfn_t pfn)
{
    xen_pfn_t dst;
    int rc;

    if ( pfn == 0 )
        return 0;

    dst = xc_dom_p2m_host(dom, pfn);
    DOMPRINTF("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "",
              __FUNCTION__, pfn, dst);
    rc = xc_clear_domain_page(dom->xch, dom->guest_domid, dst);
    if ( rc != 0 )
        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                     "%s: xc_clear_domain_page failed (pfn 0x%" PRIpfn
                     ", rc=%d)", __FUNCTION__, pfn, rc);
    return rc;
}
Пример #26
0
int xc_dom_register_external(struct xc_dom_image *dom, void *ptr, size_t size)
{
    struct xc_dom_mem *block;

    block = malloc(sizeof(*block));
    if ( block == NULL )
    {
        DOMPRINTF("%s: allocation failed", __FUNCTION__);
        return -1;
    }
    memset(block, 0, sizeof(*block));
    block->ptr = ptr;
    block->len = size;
    block->type = XC_DOM_MEM_TYPE_MALLOC_EXTERNAL;
    block->next = dom->memblocks;
    dom->memblocks = block;
    dom->alloc_malloc += sizeof(*block);
    dom->alloc_mem_map += block->len;
    return 0;
}
Пример #27
0
static int setup_hypercall_page(struct xc_dom_image *dom)
{
    DECLARE_DOMCTL;
    xen_pfn_t pfn;
    int rc;

    if ( dom->parms.virt_hypercall == -1 )
        return 0;
    pfn = (dom->parms.virt_hypercall - dom->parms.virt_base)
        >> XC_DOM_PAGE_SHIFT(dom);

    DOMPRINTF("%s: vaddr=0x%" PRIx64 " pfn=0x%" PRIpfn "", __FUNCTION__,
                  dom->parms.virt_hypercall, pfn);
    domctl.cmd = XEN_DOMCTL_hypercall_init;
    domctl.domain = dom->guest_domid;
    domctl.u.hypercall_init.gmfn = xc_dom_p2m_guest(dom, pfn);
    rc = do_domctl(dom->xch, &domctl);
    if ( rc != 0 )
        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                     "%s: HYPERCALL_INIT failed: %d - %s)",
                     __FUNCTION__, errno, strerror(errno));
    return rc;
}
Пример #28
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;
}
Пример #29
0
int xc_dom_devicetree_max_size(struct xc_dom_image *dom, size_t sz)
{
    DOMPRINTF("%s: devicetree_max_size=%zx", __FUNCTION__, sz);
    dom->max_devicetree_size = sz;
    return 0;
}
Пример #30
0
int xc_dom_ramdisk_max_size(struct xc_dom_image *dom, size_t sz)
{
    DOMPRINTF("%s: ramdisk_max_size=%zx", __FUNCTION__, sz);
    dom->max_ramdisk_size = sz;
    return 0;
}