[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v5 7/7] libxl: Introduce libxl__arch_domain_create



On Thu, 2012-02-23 at 14:51 +0000, Stefano Stabellini wrote:
> Introduce an arch specific internal domain creation function. At the
> moment only x86 provides an implementation.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>

Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

(I thought I acked this last time)

> ---
>  tools/libxl/Makefile         |    6 +-
>  tools/libxl/libxl_arch.h     |   22 ++++
>  tools/libxl/libxl_create.c   |   12 +--
>  tools/libxl/libxl_internal.h |    2 -
>  tools/libxl/libxl_noarch.c   |    8 ++
>  tools/libxl/libxl_pci.c      |  242 ---------------------------------------
>  tools/libxl/libxl_x86.c      |  259 
> ++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 294 insertions(+), 257 deletions(-)
>  create mode 100644 tools/libxl/libxl_arch.h
>  create mode 100644 tools/libxl/libxl_noarch.c
>  create mode 100644 tools/libxl/libxl_x86.c
> 
> diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
> index 41b6ac4..ba5852b 100644
> --- a/tools/libxl/Makefile
> +++ b/tools/libxl/Makefile
> @@ -34,9 +34,9 @@ LIBXL_OBJS-y += libxl_blktap2.o
>  else
>  LIBXL_OBJS-y += libxl_noblktap2.o
>  endif
> -LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
> -LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
> -LIBXL_OBJS-$(CONFIG_ARM) += libxl_nocpuid.o
> +LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o libxl_x86.o
> +LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o libxl_noarch.o
> +LIBXL_OBJS-$(CONFIG_ARM) += libxl_nocpuid.o libxl_noarch.o
> 
>  ifeq ($(CONFIG_NetBSD),y)
>  LIBXL_OBJS-y += libxl_netbsd.o
> diff --git a/tools/libxl/libxl_arch.h b/tools/libxl/libxl_arch.h
> new file mode 100644
> index 0000000..d1bbdf7
> --- /dev/null
> +++ b/tools/libxl/libxl_arch.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (C) 2012      Citrix Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; version 2.1 only. with the special
> + * exception on linking described in file LICENSE.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU Lesser General Public License for more details.
> + */
> +
> +#ifndef LIBXL_ARCH_H
> +#define LIBXL_ARCH_H
> +
> +/* arch specific internal domain creation function */
> +int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
> +               uint32_t domid);
> +
> +#endif
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index f28d814..ff589a8 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -18,6 +18,7 @@
>  #include "libxl_osdeps.h" /* must come before any other headers */
> 
>  #include "libxl_internal.h"
> +#include "libxl_arch.h"
> 
>  #include <xc_dom.h>
>  #include <xenguest.h>
> @@ -616,16 +617,7 @@ static int do_domain_create(libxl__gc *gc, 
> libxl_domain_config *d_config,
>              goto error_out;
>          }
>      }
> -
> -    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_PV &&
> -        d_config->b_info.u.pv.e820_host) {
> -        int rc;
> -        rc = libxl__e820_alloc(gc, domid, d_config);
> -        if (rc)
> -            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
> -                      "Failed while collecting E820 with: %d (errno:%d)\n",
> -                      rc, errno);
> -    }
> +    libxl__arch_domain_create(gc, d_config, domid);
>      if ( cb && (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM ||
>                  (d_config->c_info.type == LIBXL_DOMAIN_TYPE_PV &&
>                   d_config->b_info.u.pv.bootloader ))) {
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index 8846c68..bd384e2 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -975,8 +975,6 @@ _hidden int libxl__error_set(libxl__gc *gc, int code);
>  _hidden int libxl__file_reference_map(libxl_file_reference *f);
>  _hidden int libxl__file_reference_unmap(libxl_file_reference *f);
> 
> -_hidden int libxl__e820_alloc(libxl__gc *gc, uint32_t domid, 
> libxl_domain_config *d_config);
> -
>  /* parse the string @s as a sequence of 6 colon separated bytes in to @mac */
>  _hidden int libxl__parse_mac(const char *s, libxl_mac mac);
>  /* compare mac address @a and @b. 0 if the same, -ve if a<b and +ve if a>b */
> diff --git a/tools/libxl/libxl_noarch.c b/tools/libxl/libxl_noarch.c
> new file mode 100644
> index 0000000..7893535
> --- /dev/null
> +++ b/tools/libxl/libxl_noarch.c
> @@ -0,0 +1,8 @@
> +#include "libxl_internal.h"
> +#include "libxl_arch.h"
> +
> +int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
> +                              uint32_t domid)
> +{
> +    return 0;
> +}
> diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
> index 33425f5..d960f4b 100644
> --- a/tools/libxl/libxl_pci.c
> +++ b/tools/libxl/libxl_pci.c
> @@ -1147,248 +1147,6 @@ int libxl__device_pci_destroy_all(libxl__gc *gc, 
> uint32_t domid)
>      return 0;
>  }
> 
> -static const char *e820_names(int type)
> -{
> -    switch (type) {
> -        case E820_RAM: return "RAM";
> -        case E820_RESERVED: return "Reserved";
> -        case E820_ACPI: return "ACPI";
> -        case E820_NVS: return "ACPI NVS";
> -        case E820_UNUSABLE: return "Unusable";
> -        default: break;
> -    }
> -    return "Unknown";
> -}
> -
> -static int e820_sanitize(libxl_ctx *ctx, struct e820entry src[],
> -                         uint32_t *nr_entries,
> -                         unsigned long map_limitkb,
> -                         unsigned long balloon_kb)
> -{
> -    uint64_t delta_kb = 0, start = 0, start_kb = 0, last = 0, ram_end;
> -    uint32_t i, idx = 0, nr;
> -    struct e820entry e820[E820MAX];
> -
> -    if (!src || !map_limitkb || !balloon_kb || !nr_entries)
> -        return ERROR_INVAL;
> -
> -    nr = *nr_entries;
> -    if (!nr)
> -        return ERROR_INVAL;
> -
> -    if (nr > E820MAX)
> -        return ERROR_NOMEM;
> -
> -    /* Weed out anything under 1MB */
> -    for (i = 0; i < nr; i++) {
> -        if (src[i].addr > 0x100000)
> -            continue;
> -
> -        src[i].type = 0;
> -        src[i].size = 0;
> -        src[i].addr = -1ULL;
> -    }
> -
> -    /* Find the lowest and highest entry in E820, skipping over
> -     * undesired entries. */
> -    start = -1ULL;
> -    last = 0;
> -    for (i = 0; i < nr; i++) {
> -        if ((src[i].type == E820_RAM) ||
> -            (src[i].type == E820_UNUSABLE) ||
> -            (src[i].type == 0))
> -            continue;
> -
> -        start = src[i].addr < start ? src[i].addr : start;
> -        last = src[i].addr + src[i].size > last ?
> -               src[i].addr + src[i].size > last : last;
> -    }
> -    if (start > 1024)
> -        start_kb = start >> 10;
> -
> -    /* Add the memory RAM region for the guest */
> -    e820[idx].addr = 0;
> -    e820[idx].size = (uint64_t)map_limitkb << 10;
> -    e820[idx].type = E820_RAM;
> -
> -    /* .. and trim if neccessary */
> -    if (start_kb && map_limitkb > start_kb) {
> -        delta_kb = map_limitkb - start_kb;
> -        if (delta_kb)
> -            e820[idx].size -= (uint64_t)(delta_kb << 10);
> -    }
> -    /* Note: We don't touch balloon_kb here. Will add it at the end. */
> -    ram_end = e820[idx].addr + e820[idx].size;
> -    idx ++;
> -
> -    LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Memory: %"PRIu64"kB End of RAM: " \
> -               "0x%"PRIx64" (PFN) Delta: %"PRIu64"kB, PCI start: %"PRIu64"kB 
> " \
> -               "(0x%"PRIx64" PFN), Balloon %"PRIu64"kB\n", 
> (uint64_t)map_limitkb,
> -               ram_end >> 12, delta_kb, start_kb ,start >> 12,
> -               (uint64_t)balloon_kb);
> -
> -
> -    /* This whole code below is to guard against if the Intel IGD is passed 
> into
> -     * the guest. If we don't pass in IGD, this whole code can be ignored.
> -     *
> -     * The reason for this code is that Intel boxes fill their E820 with
> -     * E820_RAM amongst E820_RESERVED and we can't just ditch those E820_RAM.
> -     * That is b/c any "gaps" in the E820 is considered PCI I/O space by
> -     * Linux and it would be utilized by the Intel IGD as I/O space while
> -     * in reality it was an RAM region.
> -     *
> -     * What this means is that we have to walk the E820 and for any region
> -     * that is RAM and below 4GB and above ram_end, needs to change its type
> -     * to E820_UNUSED. We also need to move some of the E820_RAM regions if
> -     * the overlap with ram_end. */
> -    for (i = 0; i < nr; i++) {
> -        uint64_t end = src[i].addr + src[i].size;
> -
> -        /* We don't care about E820_UNUSABLE, but we need to
> -         * change the type to zero b/c the loop after this
> -         * sticks E820_UNUSABLE on the guest's E820 but ignores
> -         * the ones with type zero. */
> -        if ((src[i].type == E820_UNUSABLE) ||
> -            /* Any region that is within the "RAM region" can
> -             * be safely ditched. */
> -            (end < ram_end)) {
> -                src[i].type = 0;
> -                continue;
> -        }
> -
> -        /* Look only at RAM regions. */
> -        if (src[i].type != E820_RAM)
> -            continue;
> -
> -        /* We only care about RAM regions below 4GB. */
> -        if (src[i].addr >= (1ULL<<32))
> -            continue;
> -
> -        /* E820_RAM overlaps with our RAM region. Move it */
> -        if (src[i].addr < ram_end) {
> -            uint64_t delta;
> -
> -            src[i].type = E820_UNUSABLE;
> -            delta = ram_end - src[i].addr;
> -            /* The end < ram_end should weed this out */
> -            if (src[i].size - delta < 0)
> -                src[i].type = 0;
> -            else {
> -                src[i].size -= delta;
> -                src[i].addr = ram_end;
> -            }
> -            if (src[i].addr + src[i].size != end) {
> -                /* We messed up somewhere */
> -                src[i].type = 0;
> -                LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Computed E820 
> wrongly. Continuing on.");
> -            }
> -        }
> -        /* Lastly, convert the RAM to UNSUABLE. Look in the Linux kernel
> -           at git commit 2f14ddc3a7146ea4cd5a3d1ecd993f85f2e4f948
> -            "xen/setup: Inhibit resource API from using System RAM E820
> -           gaps as PCI mem gaps" for full explanation. */
> -        if (end > ram_end)
> -            src[i].type = E820_UNUSABLE;
> -    }
> -
> -    /* Check if there is a region between ram_end and start. */
> -    if (start > ram_end) {
> -        int add_unusable = 1;
> -        for (i = 0; i < nr && add_unusable; i++) {
> -            if (src[i].type != E820_UNUSABLE)
> -                continue;
> -            if (ram_end != src[i].addr)
> -                continue;
> -            if (start != src[i].addr + src[i].size) {
> -                /* there is one, adjust it */
> -                src[i].size = start - src[i].addr;
> -            }
> -            add_unusable = 0;
> -        }
> -        /* .. and if not present, add it in. This is to guard against
> -           the Linux guest assuming that the gap between the end of
> -           RAM region and the start of the E820_[ACPI,NVS,RESERVED]
> -           is PCI I/O space. Which it certainly is _not_. */
> -        if (add_unusable) {
> -            e820[idx].type = E820_UNUSABLE;
> -            e820[idx].addr = ram_end;
> -            e820[idx].size = start - ram_end;
> -            idx++;
> -        }
> -    }
> -    /* Almost done: copy them over, ignoring the undesireable ones */
> -    for (i = 0; i < nr; i++) {
> -        if ((src[i].type == E820_RAM) ||
> -            (src[i].type == 0))
> -            continue;
> -
> -        e820[idx].type = src[i].type;
> -        e820[idx].addr = src[i].addr;
> -        e820[idx].size = src[i].size;
> -        idx++;
> -    }
> -    /* At this point we have the mapped RAM + E820 entries from src. */
> -    if (balloon_kb) {
> -        /* and if we truncated the RAM region, then add it to the end. */
> -        e820[idx].type = E820_RAM;
> -        e820[idx].addr = (uint64_t)(1ULL << 32) > last ?
> -                         (uint64_t)(1ULL << 32) : last;
> -        /* also add the balloon memory to the end. */
> -        e820[idx].size = (uint64_t)(delta_kb << 10) +
> -                         (uint64_t)(balloon_kb << 10);
> -        idx++;
> -
> -    }
> -    nr = idx;
> -
> -    for (i = 0; i < nr; i++) {
> -      LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, ":\t[%"PRIx64" -> %"PRIx64"] %s",
> -                 e820[i].addr >> 12, (e820[i].addr + e820[i].size) >> 12,
> -                 e820_names(e820[i].type));
> -    }
> -
> -    /* Done: copy the sanitized version. */
> -    *nr_entries = nr;
> -    memcpy(src, e820, nr * sizeof(struct e820entry));
> -    return 0;
> -}
> -
> -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 (!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;
> -}
> -
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
> new file mode 100644
> index 0000000..7e11f2d
> --- /dev/null
> +++ b/tools/libxl/libxl_x86.c
> @@ -0,0 +1,259 @@
> +#include "libxl_internal.h"
> +#include "libxl_arch.h"
> +
> +static const char *e820_names(int type)
> +{
> +    switch (type) {
> +        case E820_RAM: return "RAM";
> +        case E820_RESERVED: return "Reserved";
> +        case E820_ACPI: return "ACPI";
> +        case E820_NVS: return "ACPI NVS";
> +        case E820_UNUSABLE: return "Unusable";
> +        default: break;
> +    }
> +    return "Unknown";
> +}
> +
> +static int e820_sanitize(libxl_ctx *ctx, struct e820entry src[],
> +                         uint32_t *nr_entries,
> +                         unsigned long map_limitkb,
> +                         unsigned long balloon_kb)
> +{
> +    uint64_t delta_kb = 0, start = 0, start_kb = 0, last = 0, ram_end;
> +    uint32_t i, idx = 0, nr;
> +    struct e820entry e820[E820MAX];
> +
> +    if (!src || !map_limitkb || !balloon_kb || !nr_entries)
> +        return ERROR_INVAL;
> +
> +    nr = *nr_entries;
> +    if (!nr)
> +        return ERROR_INVAL;
> +
> +    if (nr > E820MAX)
> +        return ERROR_NOMEM;
> +
> +    /* Weed out anything under 1MB */
> +    for (i = 0; i < nr; i++) {
> +        if (src[i].addr > 0x100000)
> +            continue;
> +
> +        src[i].type = 0;
> +        src[i].size = 0;
> +        src[i].addr = -1ULL;
> +    }
> +
> +    /* Find the lowest and highest entry in E820, skipping over
> +     * undesired entries. */
> +    start = -1ULL;
> +    last = 0;
> +    for (i = 0; i < nr; i++) {
> +        if ((src[i].type == E820_RAM) ||
> +            (src[i].type == E820_UNUSABLE) ||
> +            (src[i].type == 0))
> +            continue;
> +
> +        start = src[i].addr < start ? src[i].addr : start;
> +        last = src[i].addr + src[i].size > last ?
> +               src[i].addr + src[i].size > last : last;
> +    }
> +    if (start > 1024)
> +        start_kb = start >> 10;
> +
> +    /* Add the memory RAM region for the guest */
> +    e820[idx].addr = 0;
> +    e820[idx].size = (uint64_t)map_limitkb << 10;
> +    e820[idx].type = E820_RAM;
> +
> +    /* .. and trim if neccessary */
> +    if (start_kb && map_limitkb > start_kb) {
> +        delta_kb = map_limitkb - start_kb;
> +        if (delta_kb)
> +            e820[idx].size -= (uint64_t)(delta_kb << 10);
> +    }
> +    /* Note: We don't touch balloon_kb here. Will add it at the end. */
> +    ram_end = e820[idx].addr + e820[idx].size;
> +    idx ++;
> +
> +    LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Memory: %"PRIu64"kB End of RAM: " \
> +               "0x%"PRIx64" (PFN) Delta: %"PRIu64"kB, PCI start: %"PRIu64"kB 
> " \
> +               "(0x%"PRIx64" PFN), Balloon %"PRIu64"kB\n", 
> (uint64_t)map_limitkb,
> +               ram_end >> 12, delta_kb, start_kb ,start >> 12,
> +               (uint64_t)balloon_kb);
> +
> +
> +    /* This whole code below is to guard against if the Intel IGD is passed 
> into
> +     * the guest. If we don't pass in IGD, this whole code can be ignored.
> +     *
> +     * The reason for this code is that Intel boxes fill their E820 with
> +     * E820_RAM amongst E820_RESERVED and we can't just ditch those E820_RAM.
> +     * That is b/c any "gaps" in the E820 is considered PCI I/O space by
> +     * Linux and it would be utilized by the Intel IGD as I/O space while
> +     * in reality it was an RAM region.
> +     *
> +     * What this means is that we have to walk the E820 and for any region
> +     * that is RAM and below 4GB and above ram_end, needs to change its type
> +     * to E820_UNUSED. We also need to move some of the E820_RAM regions if
> +     * the overlap with ram_end. */
> +    for (i = 0; i < nr; i++) {
> +        uint64_t end = src[i].addr + src[i].size;
> +
> +        /* We don't care about E820_UNUSABLE, but we need to
> +         * change the type to zero b/c the loop after this
> +         * sticks E820_UNUSABLE on the guest's E820 but ignores
> +         * the ones with type zero. */
> +        if ((src[i].type == E820_UNUSABLE) ||
> +            /* Any region that is within the "RAM region" can
> +             * be safely ditched. */
> +            (end < ram_end)) {
> +                src[i].type = 0;
> +                continue;
> +        }
> +
> +        /* Look only at RAM regions. */
> +        if (src[i].type != E820_RAM)
> +            continue;
> +
> +        /* We only care about RAM regions below 4GB. */
> +        if (src[i].addr >= (1ULL<<32))
> +            continue;
> +
> +        /* E820_RAM overlaps with our RAM region. Move it */
> +        if (src[i].addr < ram_end) {
> +            uint64_t delta;
> +
> +            src[i].type = E820_UNUSABLE;
> +            delta = ram_end - src[i].addr;
> +            /* The end < ram_end should weed this out */
> +            if (src[i].size - delta < 0)
> +                src[i].type = 0;
> +            else {
> +                src[i].size -= delta;
> +                src[i].addr = ram_end;
> +            }
> +            if (src[i].addr + src[i].size != end) {
> +                /* We messed up somewhere */
> +                src[i].type = 0;
> +                LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Computed E820 
> wrongly. Continuing on.");
> +            }
> +        }
> +        /* Lastly, convert the RAM to UNSUABLE. Look in the Linux kernel
> +           at git commit 2f14ddc3a7146ea4cd5a3d1ecd993f85f2e4f948
> +            "xen/setup: Inhibit resource API from using System RAM E820
> +           gaps as PCI mem gaps" for full explanation. */
> +        if (end > ram_end)
> +            src[i].type = E820_UNUSABLE;
> +    }
> +
> +    /* Check if there is a region between ram_end and start. */
> +    if (start > ram_end) {
> +        int add_unusable = 1;
> +        for (i = 0; i < nr && add_unusable; i++) {
> +            if (src[i].type != E820_UNUSABLE)
> +                continue;
> +            if (ram_end != src[i].addr)
> +                continue;
> +            if (start != src[i].addr + src[i].size) {
> +                /* there is one, adjust it */
> +                src[i].size = start - src[i].addr;
> +            }
> +            add_unusable = 0;
> +        }
> +        /* .. and if not present, add it in. This is to guard against
> +           the Linux guest assuming that the gap between the end of
> +           RAM region and the start of the E820_[ACPI,NVS,RESERVED]
> +           is PCI I/O space. Which it certainly is _not_. */
> +        if (add_unusable) {
> +            e820[idx].type = E820_UNUSABLE;
> +            e820[idx].addr = ram_end;
> +            e820[idx].size = start - ram_end;
> +            idx++;
> +        }
> +    }
> +    /* Almost done: copy them over, ignoring the undesireable ones */
> +    for (i = 0; i < nr; i++) {
> +        if ((src[i].type == E820_RAM) ||
> +            (src[i].type == 0))
> +            continue;
> +
> +        e820[idx].type = src[i].type;
> +        e820[idx].addr = src[i].addr;
> +        e820[idx].size = src[i].size;
> +        idx++;
> +    }
> +    /* At this point we have the mapped RAM + E820 entries from src. */
> +    if (balloon_kb) {
> +        /* and if we truncated the RAM region, then add it to the end. */
> +        e820[idx].type = E820_RAM;
> +        e820[idx].addr = (uint64_t)(1ULL << 32) > last ?
> +                         (uint64_t)(1ULL << 32) : last;
> +        /* also add the balloon memory to the end. */
> +        e820[idx].size = (uint64_t)(delta_kb << 10) +
> +                         (uint64_t)(balloon_kb << 10);
> +        idx++;
> +
> +    }
> +    nr = idx;
> +
> +    for (i = 0; i < nr; i++) {
> +      LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, ":\t[%"PRIx64" -> %"PRIx64"] %s",
> +                 e820[i].addr >> 12, (e820[i].addr + e820[i].size) >> 12,
> +                 e820_names(e820[i].type));
> +    }
> +
> +    /* Done: copy the sanitized version. */
> +    *nr_entries = nr;
> +    memcpy(src, e820, nr * sizeof(struct e820entry));
> +    return 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 (!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 libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
> +        uint32_t domid)
> +{
> +    int rc = 0;
> +    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_PV &&
> +        d_config->b_info.u.pv.e820_host) {
> +        rc = libxl__e820_alloc(gc, domid, d_config);
> +        if (rc)
> +            LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
> +                      "Failed while collecting E820 with: %d (errno:%d)\n",
> +                      rc, errno);
> +    }
> +    return rc;
> +}
> --
> 1.7.2.5
> 



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.