Пример #1
0
static int libxl__e820_alloc(libxl__gc *gc, uint32_t domid,
        libxl_domain_config *d_config)
{
    libxl_ctx *ctx = libxl__gc_owner(gc);
    int rc;
    uint32_t nr;
    struct e820entry map[E820MAX];
    libxl_domain_build_info *b_info;

    if (d_config == NULL || d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM)
        return ERROR_INVAL;

    b_info = &d_config->b_info;
    if (!libxl_defbool_val(b_info->u.pv.e820_host))
        return ERROR_INVAL;

    nr = E820MAX;
    rc = e820_host_sanitize(gc, b_info, map, &nr);
    if (rc)
        return ERROR_FAIL;

    rc = xc_domain_set_memory_map(ctx->xch, domid, map, nr);

    if (rc < 0)
        return ERROR_FAIL;

    return 0;
}
Пример #2
0
int xc_domain_set_memmap_limit(xc_interface *xch,
                               uint32_t domid,
                               unsigned long map_limitkb)
{
    struct e820entry e820;

    e820.addr = 0;
    e820.size = (uint64_t)map_limitkb << 10;
    e820.type = E820_RAM;

    return xc_domain_set_memory_map(xch, domid, &e820, 1);
}
Пример #3
0
static int libxl__e820_alloc(libxl__gc *gc, uint32_t domid,
        libxl_domain_config *d_config)
{
    libxl_ctx *ctx = libxl__gc_owner(gc);
    int rc;
    uint32_t nr;
    struct e820entry map[E820MAX];
    libxl_domain_build_info *b_info;

    if (d_config == NULL || d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM)
        return ERROR_INVAL;

    b_info = &d_config->b_info;
    if (!libxl_defbool_val(b_info->u.pv.e820_host))
        return ERROR_INVAL;

    rc = xc_get_machine_memory_map(ctx->xch, map, E820MAX);
    if (rc < 0) {
        errno = rc;
        return ERROR_FAIL;
    }
    nr = rc;
    rc = e820_sanitize(ctx, map, &nr, b_info->target_memkb,
                       (b_info->max_memkb - b_info->target_memkb) +
                       b_info->u.pv.slack_memkb);
    if (rc)
        return ERROR_FAIL;

    rc = xc_domain_set_memory_map(ctx->xch, domid, map, nr);

    if (rc < 0) {
        errno  = rc;
        return ERROR_FAIL;
    }
    return 0;
}
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;
}
Пример #5
0
int libxl__arch_domain_construct_memmap(libxl__gc *gc,
                                        libxl_domain_config *d_config,
                                        uint32_t domid,
                                        struct xc_dom_image *dom)
{
    int rc = 0;
    unsigned int nr = 0, i;
    /* We always own at least one lowmem entry. */
    unsigned int e820_entries = 1;
    struct e820entry *e820 = NULL;
    uint64_t highmem_size =
                    dom->highmem_end ? dom->highmem_end - (1ull << 32) : 0;
    uint32_t lowmem_start = dom->device_model ? GUEST_LOW_MEM_START_DEFAULT : 0;

    /* Add all rdm entries. */
    for (i = 0; i < d_config->num_rdms; i++)
        if (d_config->rdms[i].policy != LIBXL_RDM_RESERVE_POLICY_INVALID)
            e820_entries++;


    /* If we should have a highmem range. */
    if (highmem_size)
        e820_entries++;

    if (e820_entries >= E820MAX) {
        LOG(ERROR, "Ooops! Too many entries in the memory map!");
        rc = ERROR_INVAL;
        goto out;
    }

    e820 = libxl__malloc(gc, sizeof(struct e820entry) * e820_entries);

    /* Low memory */
    e820[nr].addr = lowmem_start;
    e820[nr].size = dom->lowmem_end - lowmem_start;
    e820[nr].type = E820_RAM;
    nr++;

    /* RDM mapping */
    for (i = 0; i < d_config->num_rdms; i++) {
        if (d_config->rdms[i].policy == LIBXL_RDM_RESERVE_POLICY_INVALID)
            continue;

        e820[nr].addr = d_config->rdms[i].start;
        e820[nr].size = d_config->rdms[i].size;
        e820[nr].type = E820_RESERVED;
        nr++;
    }

    /* High memory */
    if (highmem_size) {
        e820[nr].addr = ((uint64_t)1 << 32);
        e820[nr].size = highmem_size;
        e820[nr].type = E820_RAM;
    }

    if (xc_domain_set_memory_map(CTX->xch, domid, e820, e820_entries) != 0) {
        rc = ERROR_FAIL;
        goto out;
    }

out:
    return rc;
}