int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen) { z_stream zStream; int rc; memset(&zStream, 0, sizeof(zStream)); zStream.next_in = src; zStream.avail_in = srclen; zStream.next_out = dst; zStream.avail_out = dstlen; rc = inflateInit2(&zStream, (MAX_WBITS + 32)); /* +32 means "handle gzip" */ if ( rc != Z_OK ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: inflateInit2 failed (rc=%d)\n", __FUNCTION__, rc); return -1; } rc = inflate(&zStream, Z_FINISH); inflateEnd(&zStream); if ( rc != Z_STREAM_END ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: inflate failed (rc=%d)\n", __FUNCTION__, rc); return -1; } xc_dom_printf("%s: unzip ok, 0x%zx -> 0x%zx\n", __FUNCTION__, srclen, dstlen); return 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; }
int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid, xen_pfn_t console_gmfn, xen_pfn_t xenstore_gmfn, domid_t console_domid, domid_t xenstore_domid) { xen_pfn_t gnttab_gmfn; grant_entry_v1_t *gnttab; gnttab_gmfn = xc_dom_gnttab_setup(xch, domid); if ( gnttab_gmfn == -1 ) return -1; gnttab = xc_map_foreign_range(xch, domid, PAGE_SIZE, PROT_READ|PROT_WRITE, gnttab_gmfn); if ( gnttab == NULL ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to map domU grant table " "[errno=%d]\n", __FUNCTION__, errno); return -1; } if ( domid != console_domid && console_gmfn != -1) { gnttab[GNTTAB_RESERVED_CONSOLE].flags = GTF_permit_access; gnttab[GNTTAB_RESERVED_CONSOLE].domid = console_domid; gnttab[GNTTAB_RESERVED_CONSOLE].frame = console_gmfn; } if ( domid != xenstore_domid && xenstore_gmfn != -1) { gnttab[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access; gnttab[GNTTAB_RESERVED_XENSTORE].domid = xenstore_domid; gnttab[GNTTAB_RESERVED_XENSTORE].frame = xenstore_gmfn; } if ( munmap(gnttab, PAGE_SIZE) == -1 ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to unmap domU grant table " "[errno=%d]\n", __FUNCTION__, errno); return -1; } /* Guest shouldn't really touch its grant table until it has * enabled its caches. But lets be nice. */ xc_domain_cacheflush(xch, domid, gnttab_gmfn, 1); return 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; }
void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, xen_pfn_t count) { int page_shift = XC_DOM_PAGE_SHIFT(dom); privcmd_mmap_entry_t *entries; void *ptr; int i, rc; int err; entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t)); if ( entries == NULL ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn " [malloc]\n", __FUNCTION__, pfn, count); return NULL; } ptr = mmap(NULL, count << page_shift, PROT_READ | PROT_WRITE, MAP_SHARED, dom->guest_xc, 0); if ( ptr == MAP_FAILED ) { err = errno; xc_dom_panic(XC_INTERNAL_ERROR, "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn " [mmap, errno=%i (%s)]\n", __FUNCTION__, pfn, count, err, strerror(err)); return NULL; } for ( i = 0; i < count; i++ ) { entries[i].va = (uintptr_t) ptr + (i << page_shift); entries[i].mfn = xc_dom_p2m_host(dom, pfn + i); entries[i].npages = 1; } rc = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid, entries, count); if ( rc < 0 ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn " [xenctl, rc=%d]\n", __FUNCTION__, pfn, count, rc); return NULL; } return ptr; }
static xen_pfn_t xc_dom_gnttab_setup(xc_interface *xch, domid_t domid) { gnttab_setup_table_t setup; DECLARE_HYPERCALL_BUFFER(xen_pfn_t, gmfnp); int rc; xen_pfn_t gmfn; gmfnp = xc_hypercall_buffer_alloc(xch, gmfnp, sizeof(*gmfnp)); if (gmfnp == NULL) return -1; setup.dom = domid; setup.nr_frames = 1; set_xen_guest_handle(setup.frame_list, gmfnp); setup.status = 0; rc = xc_gnttab_op(xch, GNTTABOP_setup_table, &setup, sizeof(setup), 1); gmfn = *gmfnp; xc_hypercall_buffer_free(xch, gmfnp); if ( rc != 0 || setup.status != GNTST_okay ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to setup domU grant table " "[errno=%d, status=%" PRId16 "]\n", __FUNCTION__, rc != 0 ? errno : 0, setup.status); return -1; } return gmfn; }
int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb) { unsigned int page_shift; xen_pfn_t nr_pages; dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type); if ( dom->arch_hooks == NULL ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n", __FUNCTION__); return -1; } page_shift = XC_DOM_PAGE_SHIFT(dom); nr_pages = mem_mb << (20 - page_shift); xc_dom_printf("%s: mem %d MB, pages 0x%" PRIpfn " pages, %dk each\n", __FUNCTION__, mem_mb, nr_pages, 1 << (page_shift-10)); dom->total_pages = nr_pages; xc_dom_printf("%s: 0x%" PRIpfn " pages\n", __FUNCTION__, dom->total_pages); return 0; }
static int xc_dom_probe_zimage64_kernel(struct xc_dom_image *dom) { struct zimage64_hdr *zimage; if ( dom->kernel_blob == NULL ) { xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: no kernel image loaded", __FUNCTION__); return -EINVAL; } if ( dom->kernel_size < sizeof(*zimage) ) { xc_dom_printf(dom->xch, "%s: kernel image too small", __FUNCTION__); return -EINVAL; } zimage = dom->kernel_blob; if ( zimage->magic0 != ZIMAGE64_MAGIC_V0 && zimage->magic1 != ZIMAGE64_MAGIC_V1 ) { xc_dom_printf(dom->xch, "%s: kernel is not an arm64 Image", __FUNCTION__); return -EINVAL; } return 0; }
static int xc_dom_probe_zimage32_kernel(struct xc_dom_image *dom) { uint32_t *zimage; if ( dom->kernel_blob == NULL ) { xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: no kernel image loaded", __FUNCTION__); return -EINVAL; } if ( dom->kernel_size < 0x30 /*sizeof(struct setup_header)*/ ) { xc_dom_printf(dom->xch, "%s: kernel image too small", __FUNCTION__); return -EINVAL; } zimage = (uint32_t *)dom->kernel_blob; if ( zimage[ZIMAGE32_MAGIC_OFFSET/4] != ZIMAGE32_MAGIC ) { xc_dom_printf(dom->xch, "%s: kernel is not an arm32 zImage", __FUNCTION__); return -EINVAL; } return 0; }
int xc_dom_set_arch_hooks(struct xc_dom_image *dom) { struct xc_dom_arch *hooks = first_hook; while ( hooks != NULL ) { if ( !strcmp(hooks->guest_type, dom->guest_type) ) { if ( hooks->arch_private_size ) { dom->arch_private = malloc(hooks->arch_private_size); if ( dom->arch_private == NULL ) return -1; memset(dom->arch_private, 0, hooks->arch_private_size); dom->alloc_malloc += hooks->arch_private_size; } dom->arch_hooks = hooks; return 0; } hooks = hooks->next; } xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: not found (type %s)", __FUNCTION__, dom->guest_type); return -1; }
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); xc_dom_printf("%s: supported guest type: %s%s\n", __FUNCTION__, item, match ? " <= matches" : ""); if ( match ) found++; } if ( !found ) xc_dom_panic(XC_INVALID_KERNEL, "%s: guest type %s not supported by xen kernel, sorry\n", __FUNCTION__, dom->guest_type); return found; }
static int xc_dom_chk_alloc_pages(struct xc_dom_image *dom, char *name, xen_pfn_t pages) { unsigned int page_size = XC_DOM_PAGE_SIZE(dom); if ( pages > dom->total_pages || /* multiple test avoids overflow probs */ dom->pfn_alloc_end - dom->rambase_pfn > dom->total_pages || pages > dom->total_pages - dom->pfn_alloc_end + dom->rambase_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, dom->pfn_alloc_end - dom->rambase_pfn); return -1; } dom->pfn_alloc_end += pages; dom->virt_alloc_end += pages * page_size; if ( dom->allocate ) dom->allocate(dom); return 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); if ( xc_dom_logfile ) elf_set_logfile(elf, xc_dom_logfile, 1); if ( rc != 0 ) { xc_dom_panic(XC_INVALID_KERNEL, "%s: corrupted ELF image\n", __FUNCTION__); return rc; } /* Find the section-header strings table. */ if ( elf->sec_strtab == NULL ) { xc_dom_panic(XC_INVALID_KERNEL, "%s: ELF image has no shstrtab\n", __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; /* 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); xc_dom_printf("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", __FUNCTION__, dom->guest_type, dom->kernel_seg.vstart, dom->kernel_seg.vend); return 0; }
static int xc_try_lzo1x_decode( struct xc_dom_image *dom, void **blob, size_t *size) { xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: LZO1x decompress support unavailable\n", __FUNCTION__); return -1; }
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; }
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; void *ptr; if ( start == 0 ) start = dom->virt_alloc_end; if ( start & (page_size - 1) ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: segment start isn't page aligned (0x%" PRIx64 ")\n", __FUNCTION__, start); return -1; } if ( start < dom->virt_alloc_end ) { xc_dom_panic(XC_INTERNAL_ERROR, "%s: segment start too low (0x%" PRIx64 " < 0x%" PRIx64 ")\n", __FUNCTION__, start, dom->virt_alloc_end); return -1; } seg->vstart = start; seg->vend = start + pages * page_size; seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size; dom->virt_alloc_end = seg->vend; if (dom->allocate) dom->allocate(dom, dom->virt_alloc_end); xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " -> 0x%" PRIx64 " (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)\n", __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; }
static int check_elf_kernel(struct xc_dom_image *dom, int verbose) { if ( dom->kernel_blob == NULL ) { if ( verbose ) xc_dom_panic(XC_INTERNAL_ERROR, "%s: no kernel image loaded\n", __FUNCTION__); return -EINVAL; } if ( !elf_is_elfbinary(dom->kernel_blob) ) { if ( verbose ) xc_dom_panic(XC_INVALID_KERNEL, "%s: kernel is not an ELF image\n", __FUNCTION__); return -EINVAL; } return 0; }
static elf_negerrnoval check_elf_kernel(struct xc_dom_image *dom, bool verbose) { if ( dom->kernel_blob == NULL ) { if ( verbose ) xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: no kernel image loaded", __FUNCTION__); return -EINVAL; } if ( !elf_is_elfbinary(dom->kernel_blob, dom->kernel_size) ) { if ( verbose ) xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: kernel is not an ELF image", __FUNCTION__); return -EINVAL; } return 0; }
static int launch_vm(xc_interface *xch, domid_t domid, vcpu_guest_context_any_t *ctxt) { int rc; xc_dom_printf(xch, "%s: called, ctxt=%p", __FUNCTION__, ctxt); rc = xc_vcpu_setcontext(xch, domid, 0, ctxt); if ( rc != 0 ) xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: SETVCPUCONTEXT failed (rc=%d)", __FUNCTION__, rc); return rc; }
static int xc_dom_alloc_pad(struct xc_dom_image *dom, xen_vaddr_t boundary) { unsigned int page_size = XC_DOM_PAGE_SIZE(dom); xen_pfn_t pages; if ( boundary & (page_size - 1) ) { xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: segment boundary isn't page aligned (0x%" PRIx64 ")", __FUNCTION__, boundary); return -1; } if ( boundary < dom->virt_alloc_end ) { xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: segment boundary too low (0x%" PRIx64 " < 0x%" PRIx64 ")", __FUNCTION__, boundary, dom->virt_alloc_end); return -1; } pages = (boundary - dom->virt_alloc_end) / page_size; return xc_dom_chk_alloc_pages(dom, "padding", pages); }
struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type) { struct xc_dom_arch *hooks = first_hook; while ( hooks != NULL ) { if ( !strcmp(hooks->guest_type, guest_type)) return hooks; hooks = hooks->next; } xc_dom_panic(XC_INVALID_KERNEL, "%s: not found (type %s)\n", __FUNCTION__, guest_type); return NULL; }
int xc_dom_parse_image(struct xc_dom_image *dom) { int i; xc_dom_printf("%s: called\n", __FUNCTION__); /* 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(XC_INTERNAL_ERROR, "%s: guest_type not set\n", __FUNCTION__); goto err; } /* 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(XC_INVALID_PARAM, "%s: unsupported feature requested\n", __FUNCTION__); goto err; } } return 0; err: return -1; }
void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, xen_pfn_t count) { int page_shift = XC_DOM_PAGE_SHIFT(dom); privcmd_mmap_entry_t *entries; void *ptr; int i; int err; entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t)); if ( entries == NULL ) { xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn " [malloc]", __FUNCTION__, pfn, count); return NULL; } for ( i = 0; i < count; i++ ) entries[i].mfn = xc_dom_p2m_host(dom, pfn + i); ptr = xc_map_foreign_ranges(dom->xch, dom->guest_domid, count << page_shift, PROT_READ | PROT_WRITE, 1 << page_shift, entries, count); if ( ptr == NULL ) { err = errno; xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn " [mmap, errno=%i (%s)]", __FUNCTION__, pfn, count, err, strerror(err)); return NULL; } return ptr; }
int xc_dom_ramdisk_check_size(struct xc_dom_image *dom, size_t sz) { /* No limit */ if ( !dom->max_ramdisk_size ) return 0; if ( sz > dom->max_ramdisk_size ) { xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "ramdisk image too large"); return 1; } return 0; }
int xc_dom_boot_xen_init(struct xc_dom_image *dom, xc_interface *xch, domid_t domid) { dom->xch = xch; dom->guest_domid = domid; dom->xen_version = xc_version(xch, XENVER_version, NULL); if ( xc_version(xch, XENVER_capabilities, &dom->xen_caps) < 0 ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "can't get xen capabilities"); return -1; } DOMPRINTF("%s: ver %d.%d, caps %s", __FUNCTION__, dom->xen_version >> 16, dom->xen_version & 0xff, dom->xen_caps); return 0; }
int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid) { dom->guest_xc = xc; dom->guest_domid = domid; dom->xen_version = xc_version(dom->guest_xc, XENVER_version, NULL); if ( xc_version(xc, XENVER_capabilities, &dom->xen_caps) < 0 ) { xc_dom_panic(XC_INTERNAL_ERROR, "can't get xen capabilities"); return -1; } xc_dom_printf("%s: ver %d.%d, caps %s\n", __FUNCTION__, dom->xen_version >> 16, dom->xen_version & 0xff, dom->xen_caps); return 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; }
int xc_dom_boot_mem_init(struct xc_dom_image *dom) { long rc; xc_dom_printf("%s: called\n", __FUNCTION__); rc = arch_setup_meminit(dom); if ( rc != 0 ) { xc_dom_panic(XC_OUT_OF_MEMORY, "%s: can't allocate low memory for domain\n", __FUNCTION__); return rc; } return 0; }
static int launch_vm(int xc, domid_t domid, void *ctxt) { DECLARE_DOMCTL; int rc; xc_dom_printf("%s: called, ctxt=%p\n", __FUNCTION__, ctxt); memset(&domctl, 0, sizeof(domctl)); domctl.cmd = XEN_DOMCTL_setvcpucontext; domctl.domain = domid; domctl.u.vcpucontext.vcpu = 0; set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt); rc = do_domctl(xc, &domctl); if ( rc != 0 ) xc_dom_panic(XC_INTERNAL_ERROR, "%s: SETVCPUCONTEXT failed (rc=%d)\n", __FUNCTION__, rc); return rc; }
static struct xc_dom_loader *xc_dom_find_loader(struct xc_dom_image *dom) { struct xc_dom_loader *loader = first_loader; while ( loader != NULL ) { xc_dom_printf("%s: trying %s loader ... ", __FUNCTION__, loader->name); if ( loader->probe(dom) == 0 ) { xc_dom_printf("OK\n"); return loader; } xc_dom_printf("failed\n"); loader = loader->next; } xc_dom_panic(XC_INVALID_KERNEL, "%s: no loader found\n", __FUNCTION__); return NULL; }