int stub_xc_linux_build(int c_mem_max_mib, int mem_start_mib, const char *image_name, const char *ramdisk_name, const char *cmdline, const char *features, int flags, int store_evtchn, int store_domid, int console_evtchn, int console_domid, unsigned long *store_mfn, unsigned long *console_mfn, char *protocol) { int r; struct xc_dom_image *dom; struct flags f; get_flags(&f); xc_dom_loginit(xch); dom = xc_dom_allocate(xch, cmdline, features); if (!dom) failwith_oss_xc("xc_dom_allocate"); /* The default image size limits are too large. */ xc_dom_kernel_max_size(dom, get_image_max_size("kernel")); xc_dom_ramdisk_max_size(dom, get_image_max_size("ramdisk")); configure_vcpus(f); configure_tsc(f); r = xc_dom_linux_build(xch, dom, domid, mem_start_mib, image_name, ramdisk_name, flags, store_evtchn, store_mfn, console_evtchn, console_mfn); if ( r ) failwith_oss_xc("xc_dom_linux_build"); r = construct_cpuid_policy(&f, false); if ( r ) failwith_oss_xc("construct_cpuid_policy"); r = xc_dom_gnttab_seed(xch, domid, *console_mfn, *store_mfn, console_domid, store_domid); if ( r ) failwith_oss_xc("xc_dom_gnttab_seed"); strncpy(protocol, xc_domain_get_native_protocol(xch, domid), 64); free_flags(&f); xc_dom_release(dom); return 0; }
int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid, xen_pfn_t console_gpfn, xen_pfn_t xenstore_gpfn, domid_t console_domid, domid_t xenstore_domid) { int rc; xen_pfn_t scratch_gpfn; struct xen_add_to_physmap xatp = { .domid = domid, .space = XENMAPSPACE_grant_table, .idx = 0, }; struct xen_remove_from_physmap xrfp = { .domid = domid, }; rc = xc_core_arch_get_scratch_gpfn(xch, domid, &scratch_gpfn); if ( rc < 0 ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to get a scratch gfn " "[errno=%d]\n", __FUNCTION__, errno); return -1; } xatp.gpfn = scratch_gpfn; xrfp.gpfn = scratch_gpfn; xc_dom_printf(xch, "%s: called, pfn=0x%"PRI_xen_pfn, __FUNCTION__, scratch_gpfn); rc = do_memory_op(xch, XENMEM_add_to_physmap, &xatp, sizeof(xatp)); if ( rc != 0 ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to add gnttab to physmap " "[errno=%d]\n", __FUNCTION__, errno); return -1; } rc = xc_dom_gnttab_seed(xch, domid, console_gpfn, xenstore_gpfn, console_domid, xenstore_domid); if (rc != 0) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to seed gnttab entries\n", __FUNCTION__); (void) do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp)); return -1; } rc = do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp)); if (rc != 0) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to remove gnttab from physmap " "[errno=%d]\n", __FUNCTION__, errno); return -1; } return 0; } int xc_dom_gnttab_init(struct xc_dom_image *dom) { if ( xc_dom_feature_translated(dom) ) { return xc_dom_gnttab_hvm_seed(dom->xch, dom->guest_domid, dom->console_pfn, dom->xenstore_pfn, dom->console_domid, dom->xenstore_domid); } else { return xc_dom_gnttab_seed(dom->xch, dom->guest_domid, xc_dom_p2m_host(dom, dom->console_pfn), xc_dom_p2m_host(dom, dom->xenstore_pfn), dom->console_domid, dom->xenstore_domid); } }
CAMLprim value stub_xc_linux_build_native(value xc_handle, value domid, value mem_max_mib, value mem_start_mib, value image_name, value ramdisk_name, value cmdline, value features, value flags, value store_evtchn, value store_domid, value console_evtchn, value console_domid) { CAMLparam5(xc_handle, domid, mem_max_mib, mem_start_mib, image_name); CAMLxparam5(ramdisk_name, cmdline, features, flags, store_evtchn); CAMLxparam1(console_evtchn); CAMLlocal1(result); unsigned long store_mfn; unsigned long console_mfn; int r; struct xc_dom_image *dom; char c_protocol[64]; /* Copy the ocaml values into c-land before dropping the mutex */ xc_interface *xch = _H(xc_handle); unsigned int c_mem_start_mib = Int_val(mem_start_mib); uint32_t c_domid = _D(domid); char *c_image_name = strdup(String_val(image_name)); char *c_ramdisk_name = ramdisk_name == None_val ? NULL : strdup(String_val(Field(ramdisk_name, 0))); unsigned long c_flags = Int_val(flags); unsigned int c_store_evtchn = Int_val(store_evtchn); unsigned int c_console_evtchn = Int_val(console_evtchn); struct flags f; get_flags(&f,c_domid); xc_dom_loginit(xch); dom = xc_dom_allocate(xch, String_val(cmdline), String_val(features)); if (!dom) failwith_oss_xc(xch, "xc_dom_allocate"); configure_vcpus(xch, c_domid, f); configure_tsc(xch, c_domid, f); caml_enter_blocking_section(); r = xc_dom_linux_build(xch, dom, c_domid, c_mem_start_mib, c_image_name, c_ramdisk_name, c_flags, c_store_evtchn, &store_mfn, c_console_evtchn, &console_mfn); #ifdef XENGUEST_4_2 if (r == 0) r = xc_dom_gnttab_seed(xch, c_domid, console_mfn, store_mfn, Int_val(console_domid), Int_val(store_domid)); #endif caml_leave_blocking_section(); #ifndef XEN_UNSTABLE strncpy(c_protocol, xc_dom_get_native_protocol(dom), 64); #else memset(c_protocol, '\0', 64); #endif free(c_image_name); free(c_ramdisk_name); xc_dom_release(dom); if (r != 0) failwith_oss_xc(xch, "xc_dom_linux_build"); result = caml_alloc_tuple(3); Store_field(result, 0, caml_copy_nativeint(store_mfn)); Store_field(result, 1, caml_copy_nativeint(console_mfn)); Store_field(result, 2, caml_copy_string(c_protocol)); CAMLreturn(result); }