diff options
Diffstat (limited to 'linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c')
-rw-r--r-- | linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c index d3ce58355f..032c31e532 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c @@ -56,6 +56,11 @@ struct dma_mapping_ops* dma_ops; EXPORT_SYMBOL(dma_ops); +#ifdef CONFIG_XEN_COMPAT_030002 +unsigned int __kernel_page_user; +EXPORT_SYMBOL(__kernel_page_user); +#endif + extern unsigned long *contiguous_bitmap; static unsigned long dma_reserve __initdata; @@ -260,7 +265,10 @@ static void set_pte_phys(unsigned long vaddr, return; } } - new_pte = pfn_pte(phys >> PAGE_SHIFT, prot); + if (pgprot_val(prot)) + new_pte = pfn_pte(phys >> PAGE_SHIFT, prot); + else + new_pte = __pte(0); pte = pte_offset_kernel(pmd, vaddr); if (!pte_none(*pte) && @@ -524,6 +532,33 @@ void __init xen_init_pt(void) addr = page[pud_index(__START_KERNEL_map)]; addr_to_page(addr, page); +#ifdef CONFIG_XEN_COMPAT_030002 + /* On Xen 3.0.2 and older we may need to explicitly specify _PAGE_USER + in kernel PTEs. We check that here. */ + if (HYPERVISOR_xen_version(XENVER_version, NULL) <= 0x30000) { + unsigned long *pg; + pte_t pte; + + /* Mess with the initial mapping of page 0. It's not needed. */ + BUILD_BUG_ON(__START_KERNEL <= __START_KERNEL_map); + addr = page[pmd_index(__START_KERNEL_map)]; + addr_to_page(addr, pg); + pte.pte = pg[pte_index(__START_KERNEL_map)]; + BUG_ON(!(pte.pte & _PAGE_PRESENT)); + + /* If _PAGE_USER isn't set, we obviously do not need it. */ + if (pte.pte & _PAGE_USER) { + /* _PAGE_USER is needed, but is it set implicitly? */ + pte.pte &= ~_PAGE_USER; + if ((HYPERVISOR_update_va_mapping(__START_KERNEL_map, + pte, 0) != 0) || + !(pg[pte_index(__START_KERNEL_map)] & _PAGE_USER)) + /* We need to explicitly specify _PAGE_USER. */ + __kernel_page_user = _PAGE_USER; + } + } +#endif + /* Construct mapping of initial pte page in our own directories. */ init_level4_pgt[pgd_index(__START_KERNEL_map)] = mk_kernel_pgd(__pa_symbol(level3_kernel_pgt)); @@ -913,8 +948,8 @@ void __init mem_init(void) #endif /* XEN: init and count pages outside initial allocation. */ for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { - ClearPageReserved(&mem_map[pfn]); - set_page_count(&mem_map[pfn], 1); + ClearPageReserved(pfn_to_page(pfn)); + set_page_count(pfn_to_page(pfn), 1); totalram_pages++; } reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn); |