aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2009-02-06 22:09:48 -0500
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2010-10-22 15:57:27 -0400
commit35ae11fd146384d222f3bb1f17eed1970cc92c36 (patch)
tree5d8298d9e8c41525f501003cc3c4ed18ac23ace2 /arch
parentcfd8951e082a589637f9de3c33efd3218fdb3c03 (diff)
xen: Use host-provided E820 map
Rather than simply using a flat memory map from Xen, use its provided E820 map. This allows the domain builder to tell the domain to reserve space for more pages than those initially provided at domain-build time. It also allows the host to specify holes in the address space (for PCI-passthrough, for example). Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/xen/setup.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 328b00305426..dd2eb2a9303f 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -19,6 +19,7 @@
19 19
20#include <xen/page.h> 20#include <xen/page.h>
21#include <xen/interface/callback.h> 21#include <xen/interface/callback.h>
22#include <xen/interface/memory.h>
22#include <xen/interface/physdev.h> 23#include <xen/interface/physdev.h>
23#include <xen/interface/memory.h> 24#include <xen/interface/memory.h>
24#include <xen/features.h> 25#include <xen/features.h>
@@ -107,13 +108,46 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
107 108
108char * __init xen_memory_setup(void) 109char * __init xen_memory_setup(void)
109{ 110{
111 static struct e820entry map[E820MAX] __initdata;
112
110 unsigned long max_pfn = xen_start_info->nr_pages; 113 unsigned long max_pfn = xen_start_info->nr_pages;
114 unsigned long long mem_end;
115 int rc;
116 struct xen_memory_map memmap;
117 int i;
111 118
112 max_pfn = min(MAX_DOMAIN_PAGES, max_pfn); 119 max_pfn = min(MAX_DOMAIN_PAGES, max_pfn);
120 mem_end = PFN_PHYS(max_pfn);
121
122 memmap.nr_entries = E820MAX;
123 set_xen_guest_handle(memmap.buffer, map);
124
125 rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
126 if (rc == -ENOSYS) {
127 memmap.nr_entries = 1;
128 map[0].addr = 0ULL;
129 map[0].size = mem_end;
130 /* 8MB slack (to balance backend allocations). */
131 map[0].size += 8ULL << 20;
132 map[0].type = E820_RAM;
133 rc = 0;
134 }
135 BUG_ON(rc);
113 136
114 e820.nr_map = 0; 137 e820.nr_map = 0;
115 138 for (i = 0; i < memmap.nr_entries; i++) {
116 e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM); 139 unsigned long long end = map[i].addr + map[i].size;
140 if (map[i].type == E820_RAM) {
141 if (map[i].addr > mem_end)
142 continue;
143 if (end > mem_end) {
144 /* Truncate region to max_mem. */
145 map[i].size -= end - mem_end;
146 }
147 }
148 if (map[i].size > 0)
149 e820_add_region(map[i].addr, map[i].size, map[i].type);
150 }
117 151
118 /* 152 /*
119 * Even though this is normal, usable memory under Xen, reserve 153 * Even though this is normal, usable memory under Xen, reserve