x86/mm: Make MAX_PHYSADDR_BITS and MAX_PHYSMEM_BITS dynamic
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Wed, 14 Feb 2018 11:16:54 +0000 (14:16 +0300)
committerIngo Molnar <mingo@kernel.org>
Wed, 14 Feb 2018 12:11:15 +0000 (13:11 +0100)
For boot-time switching between paging modes, we need to be able to
adjust size of physical address space at runtime.

As part of making physical address space size variable, we have to make
X86_5LEVEL dependent on SPARSEMEM_VMEMMAP. !SPARSEMEM_VMEMMAP
configuration doesn't build with variable MAX_PHYSMEM_BITS.

For !SPARSEMEM_VMEMMAP SECTIONS_WIDTH depends on MAX_PHYSMEM_BITS:

SECTIONS_WIDTH
  SECTIONS_SHIFT
    MAX_PHYSMEM_BITS

And SECTIONS_WIDTH is used on pre-processor stage, it doesn't work if it's
dyncamic. See include/linux/page-flags-layout.h.

Effect on kernel image size:

   text    data     bss     dec     hex filename
8628393 4734340 1368064 14730797  e0c62d vmlinux.before
8628892 4734340 1368064 14731296  e0c820 vmlinux.after

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
Link: http://lkml.kernel.org/r/20180214111656.88514-8-kirill.shutemov@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/Kconfig
arch/x86/include/asm/pgtable_64_types.h
arch/x86/include/asm/sparsemem.h
arch/x86/kernel/setup.c

index 92256489b8a4b428485dfd471335fd1a1d327504..fcc3f88996b33eac101e008153e111ae7e472eee 100644 (file)
@@ -1431,6 +1431,7 @@ config X86_PAE
 config X86_5LEVEL
        bool "Enable 5-level page tables support"
        select DYNAMIC_MEMORY_LAYOUT
+       select SPARSEMEM_VMEMMAP
        depends on X86_64
        ---help---
          5-level paging enables access to larger address space:
index 0c48d80e11d4520035cc0504c0f13b749076d6dd..59d971c85de5452fa80f3b99ef84ae53391dda1a 100644 (file)
@@ -95,7 +95,7 @@ extern unsigned int ptrs_per_p4d;
  * range must not overlap with anything except the KASAN shadow area, which
  * is correct as KASAN disables KASLR.
  */
-#define MAXMEM                 _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL)
+#define MAXMEM                 (1UL << MAX_PHYSMEM_BITS)
 
 #define LDT_PGD_ENTRY_L4       -3UL
 #define LDT_PGD_ENTRY_L5       -112UL
index 4fc1e9d3c43e78477d3144364eeedb4e6cb93d33..4617a2bf123ca2802e8b44b0ba3c379576722cb5 100644 (file)
 # endif
 #else /* CONFIG_X86_32 */
 # define SECTION_SIZE_BITS     27 /* matt - 128 is convenient right now */
-# ifdef CONFIG_X86_5LEVEL
-#  define MAX_PHYSADDR_BITS    52
-#  define MAX_PHYSMEM_BITS     52
-# else
-#  define MAX_PHYSADDR_BITS    44
-#  define MAX_PHYSMEM_BITS     46
-# endif
+# define MAX_PHYSADDR_BITS     (pgtable_l5_enabled ? 52 : 44)
+# define MAX_PHYSMEM_BITS      (pgtable_l5_enabled ? 52 : 46)
 #endif
 
 #endif /* CONFIG_SPARSEMEM */
index 1ae67e982af70b193498c8186f65ff27788acd9f..399d0f7fa8f1a65bbbea1374b7cc65ec83a90a37 100644 (file)
@@ -189,9 +189,7 @@ struct ist_info ist_info;
 #endif
 
 #else
-struct cpuinfo_x86 boot_cpu_data __read_mostly = {
-       .x86_phys_bits = MAX_PHYSMEM_BITS,
-};
+struct cpuinfo_x86 boot_cpu_data __read_mostly;
 EXPORT_SYMBOL(boot_cpu_data);
 #endif
 
@@ -851,6 +849,7 @@ void __init setup_arch(char **cmdline_p)
        __flush_tlb_all();
 #else
        printk(KERN_INFO "Command line: %s\n", boot_command_line);
+       boot_cpu_data.x86_phys_bits = MAX_PHYSMEM_BITS;
 #endif
 
        /*