Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[muen/linux.git] / arch / x86 / mm / init_64.c
index 6d1ff39c24382f1a474054b954fbfbcae16b6bef..0a400606dea006c5faa8fe782135f384c180f499 100644 (file)
@@ -1190,6 +1190,7 @@ void __init mem_init(void)
        /* this will put all memory onto the freelists */
        free_all_bootmem();
        after_bootmem = 1;
+       x86_init.hyper.init_after_bootmem();
 
        /*
         * Must be done after boot memory is put on freelist, because here we
@@ -1339,14 +1340,39 @@ int kern_addr_valid(unsigned long addr)
        return pfn_valid(pte_pfn(*pte));
 }
 
+/*
+ * Block size is the minimum amount of memory which can be hotplugged or
+ * hotremoved. It must be power of two and must be equal or larger than
+ * MIN_MEMORY_BLOCK_SIZE.
+ */
+#define MAX_BLOCK_SIZE (2UL << 30)
+
+/* Amount of ram needed to start using large blocks */
+#define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30)
+
 static unsigned long probe_memory_block_size(void)
 {
-       unsigned long bz = MIN_MEMORY_BLOCK_SIZE;
+       unsigned long boot_mem_end = max_pfn << PAGE_SHIFT;
+       unsigned long bz;
 
-       /* if system is UV or has 64GB of RAM or more, use large blocks */
-       if (is_uv_system() || ((max_pfn << PAGE_SHIFT) >= (64UL << 30)))
-               bz = 2UL << 30; /* 2GB */
+       /* If this is UV system, always set 2G block size */
+       if (is_uv_system()) {
+               bz = MAX_BLOCK_SIZE;
+               goto done;
+       }
 
+       /* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */
+       if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) {
+               bz = MIN_MEMORY_BLOCK_SIZE;
+               goto done;
+       }
+
+       /* Find the largest allowed block size that aligns to memory end */
+       for (bz = MAX_BLOCK_SIZE; bz > MIN_MEMORY_BLOCK_SIZE; bz >>= 1) {
+               if (IS_ALIGNED(boot_mem_end, bz))
+                       break;
+       }
+done:
        pr_info("x86/mm: Memory block size: %ldMB\n", bz >> 20);
 
        return bz;