Esempio n. 1
0
static int e820_host_sanitize(libxl__gc *gc,
                              libxl_domain_build_info *b_info,
                              struct e820entry map[],
                              uint32_t *nr)
{
    int rc;

    rc = xc_get_machine_memory_map(CTX->xch, map, *nr);
    if (rc < 0)
        return ERROR_FAIL;

    *nr = rc;

    rc = e820_sanitize(gc, map, nr, b_info->target_memkb,
                       (b_info->max_memkb - b_info->target_memkb) +
                       b_info->u.pv.slack_memkb);
    return rc;
}
Esempio n. 2
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;
}
Esempio n. 3
0
/*
 * Checks for the beginnig and end of RAM in e820 map for domain
 * and aligns start of first and end of last vNUMA memory block to
 * that map. vnode memory size are passed here Megabytes.
 * For PV guest e820 map has fixed hole sizes.
 */
int libxl__vnuma_align_mem(libxl__gc *gc,
                            uint32_t domid,
                            libxl_domain_build_info *b_info, /* IN: mem sizes */
                            vmemrange_t *memblks)        /* OUT: linux numa blocks in pfn */
{
    int i, j, rc;
    uint64_t next_start_pfn, end_max = 0, size, mem_hole;
    uint32_t nr;
    struct e820entry map[E820MAX];
    
    if (b_info->nr_vnodes == 0)
        return -EINVAL;
    libxl_ctx *ctx = libxl__gc_owner(gc);

    /* retreive e820 map for this host */
    rc = xc_get_machine_memory_map(ctx->xch, map, E820MAX);

    if (rc < 0) {
        errno = rc;
        return -EINVAL;
    }
    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)
    {   
        errno = rc;
        return -EINVAL;
    }

    /* max pfn for this host */
    for (j = nr - 1; j >= 0; j--)
        if (map[j].type == E820_RAM) {
            end_max = map[j].addr + map[j].size;
            break;
        }
    
    memset(memblks, 0, sizeof(*memblks) * b_info->nr_vnodes);
    next_start_pfn = 0;

    memblks[0].start = map[0].addr;

    for(i = 0; i < b_info->nr_vnodes; i++) {
        /* start can be not zero */
        memblks[i].start += next_start_pfn; 
        memblks[i].end = memblks[i].start + (b_info->vnuma_memszs[i] << 20);
        
        size = memblks[i].end - memblks[i].start;
        /*
         * For pv host with e820_host option turned on we need
         * to rake into account memory holes. For pv host with
         * e820_host disabled or unset, the map is contiguous 
         * RAM region.
         */ 
        if (libxl_defbool_val(b_info->u.pv.e820_host)) {
            while (mem_hole = e820_memory_hole_size(memblks[i].start,
                                                 memblks[i].end, map, nr),
                    memblks[i].end - memblks[i].start - mem_hole < size)
            {
                memblks[i].end += mem_hole;

                if (memblks[i].end > end_max) {
                    memblks[i].end = end_max;
                    break;
                }
            }
        }
        next_start_pfn = memblks[i].end;
    }
    
    if (memblks[i-1].end > end_max)
        memblks[i-1].end = end_max;

    return 0;
}