diff options
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r-- | arch/x86/xen/setup.c | 38 |
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 | ||
108 | char * __init xen_memory_setup(void) | 109 | char * __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 |