From: "Jan Beulich" Subject: [PATCH] linux/x86-64: initialization code cleanup Date: Thu, 15 May 2008 14:14:02 +0100 Message-ID: <482C533A.76E4.0078.0@novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Return-path: Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org Since init_memory_mapping() installs the pgd entry after populating all lower level tables, the whole mechanism can be coded to avoid using xen_l?_entry_update() on pages that aren't page tables (yet). Also, __set_pte() is a pure duplicate of set_pte() and hence can go away. As usual, written and tested on 2.6.25.2 and made apply to the 2.6.18 tree without further testing. Signed-off-by: Jan Beulich Index: head-2008-05-08/arch/x86_64/mm/init-xen.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- head-2008-05-08.orig/arch/x86_64/mm/init-xen.c 2008-05-08 = 15:02:32.000000000 +0200 +++ head-2008-05-08/arch/x86_64/mm/init-xen.c 2008-05-15 10:42:17.0000000= 00 +0200 @@ -60,6 +60,8 @@ unsigned int __kernel_page_user; EXPORT_SYMBOL(__kernel_page_user); #endif =20 +int after_bootmem; + extern unsigned long *contiguous_bitmap; =20 static unsigned long dma_reserve __initdata; @@ -99,6 +101,8 @@ void __meminit early_make_page_readonly( pte_t pte, *ptep; unsigned long *page =3D (unsigned long *) init_level4_pgt; =20 + BUG_ON(after_bootmem); + if (xen_feature(feature)) return; =20 @@ -236,7 +240,6 @@ void show_mem(void) printk(KERN_INFO "%lu pages swap cached\n",cached); } =20 -int after_bootmem; =20 static __init void *spp_getpage(void) {=20 @@ -440,11 +443,6 @@ static __meminit void *alloc_static_page =20 #define PTE_SIZE PAGE_SIZE =20 -static inline void __set_pte(pte_t *dst, pte_t val) -{ - *dst =3D val; -} - static inline int make_readonly(unsigned long paddr) { extern char __vsyscall_0; @@ -539,12 +537,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned=20 unsigned long pte_phys; pte_t *pte, *pte_save; =20 - if (address >=3D end) { - if (!after_bootmem) - for (; i < PTRS_PER_PMD; i++, pmd++) - set_pmd(pmd, __pmd(0)); + if (address >=3D end) break; - } pte =3D alloc_static_page(&pte_phys); pte_save =3D pte; for (k =3D 0; k < PTRS_PER_PTE; pte++, k++, address +=3D = PTE_SIZE) { @@ -557,17 +550,21 @@ phys_pmd_init(pmd_t *pmd_page, unsigned=20 for (k =3D 0; k < PTRS_PER_PTE; pte++, k++, address +=3D = PTE_SIZE) { unsigned long pteval =3D address | _PAGE_NX | = _KERNPG_TABLE; =20 - if ((address >=3D end) || - ((address >> PAGE_SHIFT) >=3D - xen_start_info->nr_pages)) + if (address >=3D (after_bootmem + ? end + : xen_start_info->nr_pages << = PAGE_SHIFT)) pteval =3D 0; else if (make_readonly(address)) pteval &=3D ~_PAGE_RW; - __set_pte(pte, __pte(pteval & __supported_pte_mask)= ); + set_pte(pte, __pte(pteval & __supported_pte_mask));= + } + if (!after_bootmem) { + early_make_page_readonly(pte_save, XENFEAT_writable= _page_tables); + *pmd =3D __pmd(pte_phys | _KERNPG_TABLE); + } else { + make_page_readonly(pte_save, XENFEAT_writable_page_= tables); + set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE)); } - pte =3D pte_save; - early_make_page_readonly(pte, XENFEAT_writable_page_tables)= ; - set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE)); } } =20 @@ -600,11 +597,13 @@ phys_pud_init(pud_t *pud_page, unsigned=20 break; =20 pmd =3D alloc_static_page(&pmd_phys); - early_make_page_readonly(pmd, XENFEAT_writable_page_tables)= ; + spin_lock(&init_mm.page_table_lock); - set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); + *pud =3D __pud(pmd_phys | _KERNPG_TABLE); phys_pmd_init(pmd, paddr, end); spin_unlock(&init_mm.page_table_lock); + + early_make_page_readonly(pmd, XENFEAT_writable_page_tables)= ; } __flush_tlb(); }=20 @@ -857,20 +855,18 @@ void init_memory_mapping(unsigned long pgd_t *pgd =3D pgd_offset_k(start); pud_t *pud; =20 - if (after_bootmem) { + if (after_bootmem) pud =3D pud_offset(pgd, start & PGDIR_MASK); - make_page_readonly(pud, XENFEAT_writable_page_table= s); - pud_phys =3D __pa(pud); - } else { + else pud =3D alloc_static_page(&pud_phys); - early_make_page_readonly(pud, XENFEAT_writable_page= _tables); - } next =3D start + PGDIR_SIZE; if (next > end)=20 next =3D end;=20 phys_pud_init(pud, __pa(start), __pa(next)); - if (!after_bootmem) + if (!after_bootmem) { + early_make_page_readonly(pud, XENFEAT_writable_page= _tables); set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys= )); + } } =20 if (!after_bootmem) {