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.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 056d11faef21..09f3059cb00b 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -33,6 +33,9 @@
33/* These are code, but not functions. Defined in entry.S */ 33/* These are code, but not functions. Defined in entry.S */
34extern const char xen_hypervisor_callback[]; 34extern const char xen_hypervisor_callback[];
35extern const char xen_failsafe_callback[]; 35extern const char xen_failsafe_callback[];
36#ifdef CONFIG_X86_64
37extern const char nmi[];
38#endif
36extern void xen_sysenter_target(void); 39extern void xen_sysenter_target(void);
37extern void xen_syscall_target(void); 40extern void xen_syscall_target(void);
38extern void xen_syscall32_target(void); 41extern void xen_syscall32_target(void);
@@ -215,13 +218,19 @@ static void __init xen_set_identity_and_release_chunk(
215 unsigned long pfn; 218 unsigned long pfn;
216 219
217 /* 220 /*
218 * If the PFNs are currently mapped, the VA mapping also needs 221 * If the PFNs are currently mapped, clear the mappings
219 * to be updated to be 1:1. 222 * (except for the ISA region which must be 1:1 mapped) to
223 * release the refcounts (in Xen) on the original frames.
220 */ 224 */
221 for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++) 225 for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++) {
226 pte_t pte = __pte_ma(0);
227
228 if (pfn < PFN_UP(ISA_END_ADDRESS))
229 pte = mfn_pte(pfn, PAGE_KERNEL_IO);
230
222 (void)HYPERVISOR_update_va_mapping( 231 (void)HYPERVISOR_update_va_mapping(
223 (unsigned long)__va(pfn << PAGE_SHIFT), 232 (unsigned long)__va(pfn << PAGE_SHIFT), pte, 0);
224 mfn_pte(pfn, PAGE_KERNEL_IO), 0); 233 }
225 234
226 if (start_pfn < nr_pages) 235 if (start_pfn < nr_pages)
227 *released += xen_release_chunk( 236 *released += xen_release_chunk(
@@ -313,6 +322,17 @@ static void xen_align_and_add_e820_region(u64 start, u64 size, int type)
313 e820_add_region(start, end - start, type); 322 e820_add_region(start, end - start, type);
314} 323}
315 324
325void xen_ignore_unusable(struct e820entry *list, size_t map_size)
326{
327 struct e820entry *entry;
328 unsigned int i;
329
330 for (i = 0, entry = list; i < map_size; i++, entry++) {
331 if (entry->type == E820_UNUSABLE)
332 entry->type = E820_RAM;
333 }
334}
335
316/** 336/**
317 * machine_specific_memory_setup - Hook for machine specific memory setup. 337 * machine_specific_memory_setup - Hook for machine specific memory setup.
318 **/ 338 **/
@@ -353,6 +373,17 @@ char * __init xen_memory_setup(void)
353 } 373 }
354 BUG_ON(rc); 374 BUG_ON(rc);
355 375
376 /*
377 * Xen won't allow a 1:1 mapping to be created to UNUSABLE
378 * regions, so if we're using the machine memory map leave the
379 * region as RAM as it is in the pseudo-physical map.
380 *
381 * UNUSABLE regions in domUs are not handled and will need
382 * a patch in the future.
383 */
384 if (xen_initial_domain())
385 xen_ignore_unusable(map, memmap.nr_entries);
386
356 /* Make sure the Xen-supplied memory map is well-ordered. */ 387 /* Make sure the Xen-supplied memory map is well-ordered. */
357 sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries); 388 sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries);
358 389
@@ -525,7 +556,13 @@ void xen_enable_syscall(void)
525 } 556 }
526#endif /* CONFIG_X86_64 */ 557#endif /* CONFIG_X86_64 */
527} 558}
528 559void __cpuinit xen_enable_nmi(void)
560{
561#ifdef CONFIG_X86_64
562 if (register_callback(CALLBACKTYPE_nmi, nmi))
563 BUG();
564#endif
565}
529void __init xen_arch_setup(void) 566void __init xen_arch_setup(void)
530{ 567{
531 xen_panic_handler_init(); 568 xen_panic_handler_init();
@@ -543,7 +580,7 @@ void __init xen_arch_setup(void)
543 580
544 xen_enable_sysenter(); 581 xen_enable_sysenter();
545 xen_enable_syscall(); 582 xen_enable_syscall();
546 583 xen_enable_nmi();
547#ifdef CONFIG_ACPI 584#ifdef CONFIG_ACPI
548 if (!(xen_start_info->flags & SIF_INITDOMAIN)) { 585 if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
549 printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); 586 printk(KERN_INFO "ACPI in unprivileged domain disabled\n");