x86/mm: Separate paging setup from memory mapping
PATCH 3/3 x86/mm: Separate paging setup from memory mapping
Move PSE and PGE bit twiddling from init_memory_mapping() to a new setup_paging() function to simplify the former function. The init_memory_mapping() function is called later in the boot process by gart_iommu_init(), efi_ioremap(), and arch_add_memory() which have no business whatsover updating the CR4 register.
--- arch/x86/include/asm/page_types.h | 2 ++ arch/x86/kernel/setup.c | 2 ++ arch/x86/mm/init.c | 23 +++++++++++++---------- 3 files changed, 17 insertions(+), 10 deletions(-)
arch/x86/include/asm/page_types.h +2 -0
@@ -51,6 +51,8 @@ static inline phys_addr_t get_max_mapped(void)return (phys_addr_t )max_pfn_mapped <<PAGE_SHIFT ; } +extern void setup_paging (void ); +extern unsigned long init_memory_mapping (unsigned long start,unsigned long end);
arch/x86/kernel/setup.c +2 -0
@@ -913,6 +913,8 @@ void __init setup_arch(char **cmdline_p)init_gbpages (); +setup_paging (); +/* max_pfn_mapped is updated here */ max_low_pfn_mapped =init_memory_mapping (0 , max_low_pfn<<PAGE_SHIFT ); max_pfn_mapped = max_low_pfn_mapped;
arch/x86/mm/init.c +13 -10
@@ -127,6 +127,19 @@ static unsigned long addr_to_pud_pfn(unsigned long addr)return (addr >>PUD_SHIFT ) << (PUD_SHIFT -PAGE_SHIFT ); } +void setup_paging (void ) +{ +/* Enable PSE if available */ +if (cpu_has_pse) +set_in_cr4 (X86_CR4_PSE ); + +/* Enable PGE if available */ +if (cpu_has_pge) { +set_in_cr4 (X86_CR4_PGE ); + __supported_pte_mask |= _PAGE_GLOBAL; + } +} +/* * Setup the direct mapping of the physical memory at PAGE_OFFSET. * This runs before bootmem is initialized and gets pages directly from
@@ -159,16 +172,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, use_gbpages = direct_gbpages;#endif -/* Enable PSE if available */ -if (cpu_has_pse) -set_in_cr4 (X86_CR4_PSE ); - -/* Enable PGE if available */ -if (cpu_has_pge) { -set_in_cr4 (X86_CR4_PGE ); - __supported_pte_mask |= _PAGE_GLOBAL; - } -if (use_gbpages) page_size_mask |=1 <<PG_LEVEL_1G ;if (use_pse)
Signature · 1 line
1.7.7.6
Quoted 5 lines · Pekka Enberg
Move PSE and PGE bit twiddling from
init_memory_mapping()to a newsetup_paging()function to simplify the former function. Theinit_memory_mapping()function is called later in the boot process bygart_iommu_init(),efi_ioremap(), andarch_add_memory()which have no business whatsover updating the CR4 register.
I have one local patch that will only set that one time too. also do other page size probe one time.
please check attached one.
Thanks
Yinghai
Subject: [PATCH 1/3] x86, mm: Introduce global page_size_mask
Add probe_page_size_mask() to detect if need to use 1G or 2M. and store them in page_size_mask.
Only probe them at first init_memory_mapping calling.
second and later init_memory_mapping() calling does not need probe again. also we don't need to pass use_gbpages around.
--- arch/x86/include/asm/pgtable.h | 1 arch/x86/mm/init.c | 70 +++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 34 deletions(-)
arch/x86/include/asm/pgtable.h +1 -0
@@ -597,6 +597,7 @@ static inline int pgd_none(pgd_t pgd)#ifndef __ASSEMBLY__extern int direct_gbpages; +extern int page_size_mask;/* local pte updates need not use xchg for locking */ static inline pte_t native_local_ptep_get_and_clear (pte_t *ptep)
arch/x86/mm/init.c +36 -34
115 lines not on this page · raw message
Quoted 5 lines · Pekka Enberg
Quoted 5 lines
Move PSE and PGE bit twiddling from
init_memory_mapping()to a newsetup_paging()function to simplify the former function. Theinit_memory_mapping()function is called later in the boot process bygart_iommu_init(),efi_ioremap(), andarch_add_memory()which have no business whatsover updating the CR4 register.
Quoted 4 lines · Yinghai Lu
I have one local patch that will only set that one time too. also do other page size probe one time.
please check attached one.
Your patch still keeps the same sort of code flow. That is, init_memory_mapping() does all sorts of things upon first call. I personally prefer the more explicit approach in this patch. In fact, you could do the page_size_mask setup in the setup_paging() function.
Pekka