aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/libxl_pci.c
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2012-05-30 08:57:52 +0100
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>2012-05-30 08:57:52 +0100
commit04cff35343fd3301003ac5be60b368b8b0c91d14 (patch)
tree031ee9b3012c3ae53017775d580234b3e2aef330 /tools/libxl/libxl_pci.c
parent45e603f6f86785c232a8b7d49a723660a7d0124b (diff)
downloadxen-04cff35343fd3301003ac5be60b368b8b0c91d14.tar.gz
xen-04cff35343fd3301003ac5be60b368b8b0c91d14.tar.bz2
xen-04cff35343fd3301003ac5be60b368b8b0c91d14.zip
libxl: move e820_names, e820_sanitize, libxl__e820_alloc to libxl_x86.c
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Acked-by: Ian Jackson <Ian.Jackson@eu.citrix.com> Acked-by: Ian Campbell <Ian.Campbell@citrix.com> Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/libxl/libxl_pci.c')
-rw-r--r--tools/libxl/libxl_pci.c242
1 files changed, 0 insertions, 242 deletions
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index a5a05a79df..de1b79f577 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -1412,248 +1412,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 || !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 (!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;
-}
-
/*
* Local variables:
* mode: C