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;
}
Example #2
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);
}