diff options
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r-- | arch/x86/xen/setup.c | 71 |
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 | ||
253 | static 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 | ||
334 | void __init xen_arch_setup(void) | 319 | void __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 | } |