aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r--arch/x86/xen/setup.c71
1 files changed, 26 insertions, 45 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index b1dbdaa23ecc..b5a7f928234b 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -23,7 +23,6 @@
23#include <xen/interface/callback.h> 23#include <xen/interface/callback.h>
24#include <xen/interface/memory.h> 24#include <xen/interface/memory.h>
25#include <xen/interface/physdev.h> 25#include <xen/interface/physdev.h>
26#include <xen/interface/memory.h>
27#include <xen/features.h> 26#include <xen/features.h>
28 27
29#include "xen-ops.h" 28#include "xen-ops.h"
@@ -118,16 +117,18 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
118 const struct e820map *e820) 117 const struct e820map *e820)
119{ 118{
120 phys_addr_t max_addr = PFN_PHYS(max_pfn); 119 phys_addr_t max_addr = PFN_PHYS(max_pfn);
121 phys_addr_t last_end = 0; 120 phys_addr_t last_end = ISA_END_ADDRESS;
122 unsigned long released = 0; 121 unsigned long released = 0;
123 int i; 122 int i;
124 123
124 /* Free any unused memory above the low 1Mbyte. */
125 for (i = 0; i < e820->nr_map && last_end < max_addr; i++) { 125 for (i = 0; i < e820->nr_map && last_end < max_addr; i++) {
126 phys_addr_t end = e820->map[i].addr; 126 phys_addr_t end = e820->map[i].addr;
127 end = min(max_addr, end); 127 end = min(max_addr, end);
128 128
129 released += xen_release_chunk(last_end, end); 129 if (last_end < end)
130 last_end = e820->map[i].addr + e820->map[i].size; 130 released += xen_release_chunk(last_end, end);
131 last_end = max(last_end, e820->map[i].addr + e820->map[i].size);
131 } 132 }
132 133
133 if (last_end < max_addr) 134 if (last_end < max_addr)
@@ -164,6 +165,7 @@ char * __init xen_memory_setup(void)
164 XENMEM_memory_map; 165 XENMEM_memory_map;
165 rc = HYPERVISOR_memory_op(op, &memmap); 166 rc = HYPERVISOR_memory_op(op, &memmap);
166 if (rc == -ENOSYS) { 167 if (rc == -ENOSYS) {
168 BUG_ON(xen_initial_domain());
167 memmap.nr_entries = 1; 169 memmap.nr_entries = 1;
168 map[0].addr = 0ULL; 170 map[0].addr = 0ULL;
169 map[0].size = mem_end; 171 map[0].size = mem_end;
@@ -179,34 +181,32 @@ char * __init xen_memory_setup(void)
179 for (i = 0; i < memmap.nr_entries; i++) { 181 for (i = 0; i < memmap.nr_entries; i++) {
180 unsigned long long end = map[i].addr + map[i].size; 182 unsigned long long end = map[i].addr + map[i].size;
181 183
182 if (map[i].type == E820_RAM) { 184 if (map[i].type == E820_RAM && end > mem_end) {
183 if (map[i].addr < mem_end && end > mem_end) { 185 /* RAM off the end - may be partially included */
184 /* Truncate region to max_mem. */ 186 u64 delta = min(map[i].size, end - mem_end);
185 u64 delta = end - mem_end;
186 187
187 map[i].size -= delta; 188 map[i].size -= delta;
188 extra_pages += PFN_DOWN(delta); 189 end -= delta;
189 190
190 end = mem_end; 191 extra_pages += PFN_DOWN(delta);
191 }
192 } 192 }
193 193
194 if (end > xen_extra_mem_start) 194 if (map[i].size > 0 && end > xen_extra_mem_start)
195 xen_extra_mem_start = end; 195 xen_extra_mem_start = end;
196 196
197 /* If region is non-RAM or below mem_end, add what remains */ 197 /* Add region if any remains */
198 if ((map[i].type != E820_RAM || map[i].addr < mem_end) && 198 if (map[i].size > 0)
199 map[i].size > 0)
200 e820_add_region(map[i].addr, map[i].size, map[i].type); 199 e820_add_region(map[i].addr, map[i].size, map[i].type);
201 } 200 }
202 201
203 /* 202 /*
204 * Even though this is normal, usable memory under Xen, reserve 203 * In domU, the ISA region is normal, usable memory, but we
205 * ISA memory anyway because too many things think they can poke 204 * reserve ISA memory anyway because too many things poke
206 * about in there. 205 * about in there.
207 * 206 *
208 * In a dom0 kernel, this region is identity mapped with the 207 * In Dom0, the host E820 information can leave gaps in the
209 * hardware ISA area, so it really is out of bounds. 208 * ISA range, which would cause us to release those pages. To
209 * avoid this, we unconditionally reserve them here.
210 */ 210 */
211 e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, 211 e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS,
212 E820_RESERVED); 212 E820_RESERVED);
@@ -244,26 +244,11 @@ char * __init xen_memory_setup(void)
244 else 244 else
245 extra_pages = 0; 245 extra_pages = 0;
246 246
247 if (!xen_initial_domain()) 247 xen_add_extra_mem(extra_pages);
248 xen_add_extra_mem(extra_pages);
249 248
250 return "Xen"; 249 return "Xen";
251} 250}
252 251
253static void xen_idle(void)
254{
255 local_irq_disable();
256
257 if (need_resched())
258 local_irq_enable();
259 else {
260 current_thread_info()->status &= ~TS_POLLING;
261 smp_mb__after_clear_bit();
262 safe_halt();
263 current_thread_info()->status |= TS_POLLING;
264 }
265}
266
267/* 252/*
268 * Set the bit indicating "nosegneg" library variants should be used. 253 * Set the bit indicating "nosegneg" library variants should be used.
269 * We only need to bother in pure 32-bit mode; compat 32-bit processes 254 * We only need to bother in pure 32-bit mode; compat 32-bit processes
@@ -333,9 +318,6 @@ void __cpuinit xen_enable_syscall(void)
333 318
334void __init xen_arch_setup(void) 319void __init xen_arch_setup(void)
335{ 320{
336 struct physdev_set_iopl set_iopl;
337 int rc;
338
339 xen_panic_handler_init(); 321 xen_panic_handler_init();
340 322
341 HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); 323 HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
@@ -352,11 +334,6 @@ void __init xen_arch_setup(void)
352 xen_enable_sysenter(); 334 xen_enable_sysenter();
353 xen_enable_syscall(); 335 xen_enable_syscall();
354 336
355 set_iopl.iopl = 1;
356 rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
357 if (rc != 0)
358 printk(KERN_INFO "physdev_op failed %d\n", rc);
359
360#ifdef CONFIG_ACPI 337#ifdef CONFIG_ACPI
361 if (!(xen_start_info->flags & SIF_INITDOMAIN)) { 338 if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
362 printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); 339 printk(KERN_INFO "ACPI in unprivileged domain disabled\n");
@@ -368,7 +345,11 @@ void __init xen_arch_setup(void)
368 MAX_GUEST_CMDLINE > COMMAND_LINE_SIZE ? 345 MAX_GUEST_CMDLINE > COMMAND_LINE_SIZE ?
369 COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE); 346 COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE);
370 347
371 pm_idle = xen_idle; 348 /* Set up idle, making sure it calls safe_halt() pvop */
349#ifdef CONFIG_X86_32
350 boot_cpu_data.hlt_works_ok = 1;
351#endif
352 pm_idle = default_idle;
372 353
373 fiddle_vdso(); 354 fiddle_vdso();
374} 355}