aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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