x86 fixes
Subsystems (3)
Linus,
Please pull the latest x86-fixes-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git x86-fixes-for-linus
Thanks,
Ingo
------------------>
Stefano Stabellini (2):
xen: set max_pfn_mapped to the last pfn mapped
xen: update mask_rw_pte after kernel page tables init changes
Yinghai Lu (1):
x86: Cleanup highmap after brk is concluded
arch/x86/kernel/head64.c | 3 --- arch/x86/kernel/setup.c | 25 +++---------------------- arch/x86/mm/init_64.c | 11 ++++++----- arch/x86/xen/mmu.c | 21 ++++++++++++--------- 4 files changed, 21 insertions(+), 39 deletions(-)
arch/x86/kernel/head64.c +0 -3
@@ -77,9 +77,6 @@ void __init x86_64_start_kernel(char * real_mode_data)/* Make NULL pointers segfault */ zap_identity_mappings (); -/* Cleanup the over mapped high alias */ -cleanup_highmap (); - max_pfn_mapped =KERNEL_IMAGE_SIZE >>PAGE_SHIFT ;for (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++) {
arch/x86/kernel/setup.c +3 -22
@@ -294,30 +294,11 @@ static void __init init_gbpages(void) else direct_gbpages = 0; } - -static void __init cleanup_highmap_brk_end (void ) -{ -pud_t *pud; -pmd_t *pmd; - - mmu_cr4_features =read_cr4 (); - -/* -* _brk_end cannot change anymore, but it and _end may be -* located on different 2M pages. cleanup_highmap(), however, -* can only consider _end when it runs, so destroy any -* mappings beyond _brk_end here. -*/ - pud =pud_offset (pgd_offset_k (_brk_end), _brk_end); - pmd =pmd_offset (pud, _brk_end -1 ); -while (++pmd <=pmd_offset (pud, (unsigned long )_end -1 )) -pmd_clear (pmd); -}#else static inline void init_gbpages (void ) { } -static inline void cleanup_highmap_brk_end (void ) +static void __init cleanup_highmap (void ) { }#endif
@@ -330,8 +311,6 @@ static void __init reserve_brk(void)/* Mark brk area as locked down and no longer taking any new allocations */ _brk_start =0 ; - -cleanup_highmap_brk_end (); }#ifdef CONFIG_BLK_DEV_INITRD
@@ -950,6 +929,8 @@ void __init setup_arch(char **cmdline_p)*/ reserve_brk (); +cleanup_highmap (); + memblock.current_limit =get_max_mapped ();memblock_x86_fill ();
arch/x86/mm/init_64.c +6 -5
@@ -51,6 +51,7 @@#include <asm/numa.h> #include <asm/cacheflush.h> #include <asm/init.h> +#include <asm/setup.h> static int __init parse_direct_gbpages_off (char *arg) {
@@ -293,18 +294,18 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)* to the compile time generated pmds. This results in invalid pmds up * to the point where we hit the physaddr 0 mapping. * -* We limit the mappings to the region from _text to _end. _end is -* rounded up to the 2MB boundary. This catches the invalid pmds as +* We limit the mappings to the region from _text to _brk_end. _brk_end +* is rounded up to the 2MB boundary. This catches the invalid pmds as * well, as they are located before _text: */ void __init cleanup_highmap (void ) {unsigned long vaddr = __START_KERNEL_map; -unsigned long end =roundup ((unsigned long )_end,PMD_SIZE ) -1 ; +unsigned long vaddr_end = __START_KERNEL_map + (max_pfn_mapped <<PAGE_SHIFT ); +unsigned long end =roundup ((unsigned long )_brk_end,PMD_SIZE ) -1 ;pmd_t *pmd = level2_kernel_pgt; -pmd_t *last_pmd = pmd +PTRS_PER_PMD ; -for (; pmd < last_pmd; pmd++, vaddr +=PMD_SIZE ) { +for (; vaddr +PMD_SIZE -1 < vaddr_end; pmd++, vaddr +=PMD_SIZE ) {if (pmd_none (*pmd))continue ;if (vaddr < (unsigned long ) _text || vaddr > end)
arch/x86/xen/mmu.c +12 -9
@@ -1488,10 +1488,12 @@ static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)/* * If the new pfn is within the range of the newly allocated * kernel pagetable, and it isn't being mapped into an -* early_ioremap fixmap slot, make sure it is RO. +* early_ioremap fixmap slot as a freshly allocated page, make sure +* it is RO. */ -if (!is_early_ioremap_ptep (ptep) && - pfn >= pgt_buf_start && pfn < pgt_buf_end) +if (((!is_early_ioremap_ptep (ptep) && + pfn >= pgt_buf_start && pfn < pgt_buf_end)) || + (is_early_ioremap_ptep (ptep) && pfn != (pgt_buf_end -1 ))) pte =pte_wrprotect (pte);return pte;
@@ -1701,9 +1703,6 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)for (pteidx =0 ; pteidx <PTRS_PER_PTE ; pteidx++, pfn++) {pte_t pte; -if (pfn > max_pfn_mapped) - max_pfn_mapped = pfn; -if (!pte_none (pte_page[pteidx]))continue ;
@@ -1761,6 +1760,12 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,pud_t *l3;pmd_t *l2; +/* max_pfn_mapped is the last pfn mapped in the initial memory +* mappings. Considering that on Xen after the kernel mappings we +* have the mappings of some pages that don't exist in pfn space, we +* set max_pfn_mapped to the last real pfn mapped. */ + max_pfn_mapped =PFN_DOWN (__pa (xen_start_info->mfn_list)); +/* Zap identity mapping */ init_level4_pgt[0 ] =__pgd (0 );
@@ -1865,9 +1870,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, initial_kernel_pmd =extend_brk (sizeof (pmd_t) *PTRS_PER_PMD ,PAGE_SIZE ); - max_pfn_mapped =PFN_DOWN (__pa (xen_start_info->pt_base) + - xen_start_info->nr_pt_frames *PAGE_SIZE + -512 *1024 ); + max_pfn_mapped =PFN_DOWN (__pa (xen_start_info->mfn_list)); kernel_pmd =m2v (pgd[KERNEL_PGD_BOUNDARY ].pgd);memcpy (initial_kernel_pmd, kernel_pmd,sizeof (pmd_t) *PTRS_PER_PMD );