diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index c04e14e6b301881c6d3b2bf6cda8ac3b29b6800a..1982617fa9c71e01c17f35a5d9f3063d7b8f51be 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -116,6 +116,7 @@ static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss; DEFINE_PER_CPU(unsigned long, xen_cr3); /* cr3 stored as physaddr */ DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */ +static phys_addr_t xen_pt_base, xen_pt_size __initdata; /* * Just beyond the highest usermode address. STACK_TOP_MAX has a @@ -1998,7 +1999,9 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) check_pt_base(&pt_base, &pt_end, addr[i]); /* Our (by three pages) smaller Xen pagetable that we are using */ - memblock_reserve(PFN_PHYS(pt_base), (pt_end - pt_base) * PAGE_SIZE); + xen_pt_base = PFN_PHYS(pt_base); + xen_pt_size = (pt_end - pt_base) * PAGE_SIZE; + memblock_reserve(xen_pt_base, xen_pt_size); /* protect xen_start_info */ memblock_reserve(__pa(xen_start_info), PAGE_SIZE); /* Revector the xen_start_info */ @@ -2074,11 +2077,21 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) PFN_DOWN(__pa(initial_page_table))); xen_write_cr3(__pa(initial_page_table)); - memblock_reserve(__pa(xen_start_info->pt_base), - xen_start_info->nr_pt_frames * PAGE_SIZE); + xen_pt_base = __pa(xen_start_info->pt_base); + xen_pt_size = xen_start_info->nr_pt_frames * PAGE_SIZE; + + memblock_reserve(xen_pt_base, xen_pt_size); } #endif /* CONFIG_X86_64 */ +void __init xen_pt_check_e820(void) +{ + if (xen_is_e820_reserved(xen_pt_base, xen_pt_size)) { + xen_raw_console_write("Xen hypervisor allocated page table memory conflicts with E820 map\n"); + BUG(); + } +} + static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss; static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 9bd3f358f3d9963195fcde74d3622505b92f3ada..3fca9c114828d02c9a32dad17240c566ae427763 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -802,6 +802,12 @@ char * __init xen_memory_setup(void) BUG(); } + /* + * Check for a conflict of the hypervisor supplied page tables with + * the target E820 map. + */ + xen_pt_check_e820(); + xen_reserve_xen_mfnlist(); /* diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index c4c3c23597a56079846e42468b93af65bab5a885..9038a0f1d5a1fc6e09c0d1895ea4b1a237449b57 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -35,6 +35,7 @@ void xen_build_mfn_list_list(void); void xen_setup_machphys_mapping(void); void xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); void xen_reserve_top(void); +void __init xen_pt_check_e820(void); void xen_mm_pin_all(void); void xen_mm_unpin_all(void);