aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/x86/xen/setup.c38
-rw-r--r--include/xen/interface/memory.h29
2 files changed, 65 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
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index d3938d3e71f8..d7a6c13bde69 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -186,6 +186,35 @@ struct xen_translate_gpfn_list {
186}; 186};
187DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list); 187DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list);
188 188
189/*
190 * Returns the pseudo-physical memory map as it was when the domain
191 * was started (specified by XENMEM_set_memory_map).
192 * arg == addr of struct xen_memory_map.
193 */
194#define XENMEM_memory_map 9
195struct xen_memory_map {
196 /*
197 * On call the number of entries which can be stored in buffer. On
198 * return the number of entries which have been stored in
199 * buffer.
200 */
201 unsigned int nr_entries;
202
203 /*
204 * Entries in the buffer are in the same format as returned by the
205 * BIOS INT 0x15 EAX=0xE820 call.
206 */
207 GUEST_HANDLE(void) buffer;
208};
209DEFINE_GUEST_HANDLE_STRUCT(xen_memory_map);
210
211/*
212 * Returns the real physical memory map. Passes the same structure as
213 * XENMEM_memory_map.
214 * arg == addr of struct xen_memory_map.
215 */
216#define XENMEM_machine_memory_map 10
217
189 218
190/* 219/*
191 * Prevent the balloon driver from changing the memory reservation 220 * Prevent the balloon driver from changing the memory reservation