Example #1
0
/*
 * restore_ops function.  Sets extra hvm parameters and seeds the grant table.
 */
static int x86_hvm_stream_complete(struct xc_sr_context *ctx)
{
    xc_interface *xch = ctx->xch;
    int rc;

    rc = xc_hvm_param_set(xch, ctx->domid, HVM_PARAM_STORE_EVTCHN,
                          ctx->restore.xenstore_evtchn);
    if ( rc )
    {
        PERROR("Failed to set HVM_PARAM_STORE_EVTCHN");
        return rc;
    }

    rc = xc_hvm_param_set(xch, ctx->domid, HVM_PARAM_CONSOLE_EVTCHN,
                          ctx->restore.console_evtchn);
    if ( rc )
    {
        PERROR("Failed to set HVM_PARAM_CONSOLE_EVTCHN");
        return rc;
    }

    rc = xc_domain_hvm_setcontext(xch, ctx->domid,
                                  ctx->x86_hvm.restore.context,
                                  ctx->x86_hvm.restore.contextsz);
    if ( rc < 0 )
    {
        PERROR("Unable to restore HVM context");
        return rc;
    }

    rc = xc_dom_gnttab_hvm_seed(xch, ctx->domid,
                                ctx->restore.console_gfn,
                                ctx->restore.xenstore_gfn,
                                ctx->restore.console_domid,
                                ctx->restore.xenstore_domid);
    if ( rc )
    {
        PERROR("Failed to seed grant table");
        return rc;
    }

#ifdef XG_LIBXL_HVM_COMPAT
    rc = handle_qemu(ctx);
    if ( rc )
    {
        ERROR("Failed to dump qemu");
        return rc;
    }
#endif

    return rc;
}
int stub_xc_hvm_build_with_mem(uint64_t max_mem_mib, uint64_t max_start_mib,
                               const char *image)
{
    uint64_t lowmem_end, highmem_start, highmem_end, mmio_start;
    struct xc_hvm_build_args args = {
        .mem_size   = max_mem_mib   << 20,
        .mem_target = max_start_mib << 20,
        .mmio_size  = HVM_BELOW_4G_MMIO_LENGTH,
        .image_file_name = image,
    };
    unsigned int i, j, nr = 0;
    struct e820entry *e820;
    int rc;
    unsigned int nr_rdm_entries[MAX_RMRR_DEVICES] = {0};
    unsigned int nr_rmrr_devs = 0;
    struct xen_reserved_device_memory *xrdm[MAX_RMRR_DEVICES] = {0};
    unsigned long rmrr_overlapped_ram = 0;
    char *s;

    if ( pci_passthrough_sbdf_list )
    {
        s = strtok(pci_passthrough_sbdf_list,",");
        while ( s != NULL )
        {
            unsigned int seg, bus, device, func;
            xg_info("Getting RMRRs for device '%s'\n",s);
            if ( parse_pci_sbdf(s, &seg, &bus, &device, &func) )
            {
                if ( !get_rdm(seg, bus, (device << 3) + func,
                        &nr_rdm_entries[nr_rmrr_devs], &xrdm[nr_rmrr_devs]) )
                    nr_rmrr_devs++;
            }
            if ( nr_rmrr_devs == MAX_RMRR_DEVICES )
            {
                xg_err("Error: hit limit of %d RMRR devices for domain\n",
                            MAX_RMRR_DEVICES);
                exit(1);
            }
            s = strtok (NULL, ",");
        }
    }
    e820 = malloc(sizeof(*e820) * E820MAX);
    if (!e820)
	    return -ENOMEM;

    lowmem_end  = args.mem_size;
    highmem_end = highmem_start = 1ull << 32;
    mmio_start  = highmem_start - args.mmio_size;

    if ( lowmem_end > mmio_start )
    {
        highmem_end = (1ull << 32) + (lowmem_end - mmio_start);
        lowmem_end = mmio_start;
    }

    args.lowmem_end = lowmem_end;
    args.highmem_end = highmem_end;
    args.mmio_start = mmio_start;

    /* Leave low 1MB to HVMLoader... */
    e820[nr].addr = 0x100000u;
    e820[nr].size = args.lowmem_end - 0x100000u;
    e820[nr].type = E820_RAM;
    nr++;

    /* RDM mapping */
    for (i = 0; i < nr_rmrr_devs; i++)
    {
        for (j = 0; j < nr_rdm_entries[i]; j++)
        {
            e820[nr].addr = xrdm[i][j].start_pfn << XC_PAGE_SHIFT;
            e820[nr].size = xrdm[i][j].nr_pages << XC_PAGE_SHIFT;
            e820[nr].type = E820_RESERVED;
            xg_info("Adding RMRR 0x%lx size 0x%lx\n", e820[nr].addr, e820[nr].size);
            if ( e820[nr].addr < args.lowmem_end ) {
                rmrr_overlapped_ram += ( args.lowmem_end - e820[nr].addr );
                args.lowmem_end = e820[nr].addr;
            }
            nr++;
        }
    }
    e820[0].size -= rmrr_overlapped_ram;
    args.highmem_end += rmrr_overlapped_ram;
    args.mmio_size += rmrr_overlapped_ram;
    args.mmio_start -= rmrr_overlapped_ram;

    for (i = 0; i < nr_rmrr_devs; i++)
    {
        free(xrdm[i]);
    }

    if ( args.highmem_end > highmem_start )
    {
        e820[nr].addr = highmem_start;
        e820[nr].size = args.highmem_end - e820[nr].addr;
        e820[nr].type = E820_RAM;
        nr++;
    }

    rc = xc_hvm_build(xch, domid, &args);

    if (!rc)
        rc = xc_domain_set_memory_map(xch, domid, e820, nr);

    free(e820);

    return rc;
}

int stub_xc_hvm_build(int mem_max_mib, int mem_start_mib, const char *image_name,
                      int store_evtchn, int store_domid,
                      int console_evtchn, int console_domid,
                      unsigned long *store_mfn, unsigned long *console_mfn)
{
    int r;
    struct flags f;
    get_flags(&f);

    configure_vcpus(f);
    configure_tsc(f);

    r = stub_xc_hvm_build_with_mem(mem_max_mib, mem_start_mib, image_name);
    if ( r )
        failwith_oss_xc("hvm_build");

    r = hvm_build_set_params(store_evtchn, store_mfn,
                             console_evtchn, console_mfn, f);
    if ( r )
        failwith_oss_xc("hvm_build_params");

    r = construct_cpuid_policy(&f, true);
    if ( r )
        failwith_oss_xc("construct_cpuid_policy");

    r = xc_dom_gnttab_hvm_seed(xch, domid, *console_mfn, *store_mfn,
                               console_domid, store_domid);
    if ( r )
        failwith_oss_xc("xc_dom_gnttab_hvm_seed");

    free_flags(&f);

    return 0;
}
Example #3
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_hvm_build_native(value xc_handle, value domid,
    value mem_max_mib, value mem_start_mib, value image_name,
										value store_evtchn, value store_domid,
										value console_evtchn, value console_domid)
{
	CAMLparam5(xc_handle, domid, mem_max_mib, mem_start_mib, image_name);
	CAMLxparam2(store_evtchn, console_evtchn);
	CAMLlocal1(result);

	char *image_name_c = strdup(String_val(image_name));
	xc_interface *xch;

	unsigned long store_mfn=0;
  unsigned long console_mfn=0;
	int r;
	struct flags f;
	/* The xenguest interface changed and was backported to XCP: */
#if defined(XENGUEST_HAS_HVM_BUILD_ARGS) || (__XEN_LATEST_INTERFACE_VERSION__ >= 0x00040200)
	struct xc_hvm_build_args args;
	memset(&args, 0, sizeof(struct xc_hvm_build_args));
#endif
	get_flags(&f, _D(domid));

	xch = _H(xc_handle);
	configure_vcpus(xch, _D(domid), f);
	configure_tsc(xch, _D(domid), f);

#if defined(XENGUEST_HAS_HVM_BUILD_ARGS) || (__XEN_LATEST_INTERFACE_VERSION__ >= 0x00040200)
	args.mem_size = (uint64_t)Int_val(mem_max_mib) << 20;
	args.mem_target = (uint64_t)Int_val(mem_start_mib) << 20;
	args.mmio_size = f.mmio_size_mib << 20;
	args.image_file_name = image_name_c;
#endif

	caml_enter_blocking_section ();
#if defined(XENGUEST_HAS_HVM_BUILD_ARGS) || (__XEN_LATEST_INTERFACE_VERSION__ >= 0x00040200)
	r = xc_hvm_build(xch, _D(domid), &args);
#else
	r = xc_hvm_build_target_mem(xch, _D(domid),
				    Int_val(mem_max_mib),
				    Int_val(mem_start_mib),
				    image_name_c);
#endif
	caml_leave_blocking_section ();

	free(image_name_c);

	if (r)
		failwith_oss_xc(xch, "hvm_build");


	r = hvm_build_set_params(xch, _D(domid), Int_val(store_evtchn), &store_mfn, 
                           Int_val(console_evtchn), &console_mfn, f);
	if (r)
		failwith_oss_xc(xch, "hvm_build_params");
#ifdef XENGUEST_4_2
    xc_dom_gnttab_hvm_seed(xch, _D(domid), console_mfn, store_mfn, Int_val(console_domid), Int_val(store_domid));
#endif

  result = caml_alloc_tuple(2);
  Store_field(result, 0, caml_copy_nativeint(store_mfn));
  Store_field(result, 1, caml_copy_nativeint(console_mfn));

	CAMLreturn(result);
}