diff options
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r-- | arch/x86/xen/setup.c | 51 |
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 */ |
34 | extern const char xen_hypervisor_callback[]; | 34 | extern const char xen_hypervisor_callback[]; |
35 | extern const char xen_failsafe_callback[]; | 35 | extern const char xen_failsafe_callback[]; |
36 | #ifdef CONFIG_X86_64 | ||
37 | extern const char nmi[]; | ||
38 | #endif | ||
36 | extern void xen_sysenter_target(void); | 39 | extern void xen_sysenter_target(void); |
37 | extern void xen_syscall_target(void); | 40 | extern void xen_syscall_target(void); |
38 | extern void xen_syscall32_target(void); | 41 | extern 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 | ||
325 | void 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 | 559 | void __cpuinit xen_enable_nmi(void) | |
560 | { | ||
561 | #ifdef CONFIG_X86_64 | ||
562 | if (register_callback(CALLBACKTYPE_nmi, nmi)) | ||
563 | BUG(); | ||
564 | #endif | ||
565 | } | ||
529 | void __init xen_arch_setup(void) | 566 | void __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"); |