Merge remote-tracking branch 'arm64/for-next/fixes' into for-next/core
[sfrench/cifs-2.6.git] / arch / riscv / mm / init.c
index ea933b789a882f29bec8b1f81892747764b7de3e..8e577f14f1205d67eaf3ec44b0df941a598da0a6 100644 (file)
@@ -154,9 +154,8 @@ disable:
 
 void __init setup_bootmem(void)
 {
-       phys_addr_t mem_size = 0;
-       phys_addr_t total_mem = 0;
-       phys_addr_t mem_start, start, end = 0;
+       phys_addr_t mem_start = 0;
+       phys_addr_t start, end = 0;
        phys_addr_t vmlinux_end = __pa_symbol(&_end);
        phys_addr_t vmlinux_start = __pa_symbol(&_start);
        u64 i;
@@ -164,21 +163,18 @@ void __init setup_bootmem(void)
        /* Find the memory region containing the kernel */
        for_each_mem_range(i, &start, &end) {
                phys_addr_t size = end - start;
-               if (!total_mem)
+               if (!mem_start)
                        mem_start = start;
                if (start <= vmlinux_start && vmlinux_end <= end)
                        BUG_ON(size == 0);
-               total_mem = total_mem + size;
        }
 
        /*
-        * Remove memblock from the end of usable area to the
-        * end of region
+        * The maximal physical memory size is -PAGE_OFFSET.
+        * Make sure that any memory beyond mem_start + (-PAGE_OFFSET) is removed
+        * as it is unusable by kernel.
         */
-       mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET);
-       if (mem_start + mem_size < end)
-               memblock_remove(mem_start + mem_size,
-                               end - mem_start - mem_size);
+       memblock_enforce_memory_limit(mem_start - PAGE_OFFSET);
 
        /* Reserve from the start of the kernel to the end of the kernel */
        memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
@@ -297,6 +293,7 @@ pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss;
 #define NUM_EARLY_PMDS         (1UL + MAX_EARLY_MAPPING_SIZE / PGDIR_SIZE)
 #endif
 pmd_t early_pmd[PTRS_PER_PMD * NUM_EARLY_PMDS] __initdata __aligned(PAGE_SIZE);
+pmd_t early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
 
 static pmd_t *__init get_pmd_virt_early(phys_addr_t pa)
 {
@@ -494,6 +491,18 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
                                   load_pa + (va - PAGE_OFFSET),
                                   map_size, PAGE_KERNEL_EXEC);
 
+#ifndef __PAGETABLE_PMD_FOLDED
+       /* Setup early PMD for DTB */
+       create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
+                          (uintptr_t)early_dtb_pmd, PGDIR_SIZE, PAGE_TABLE);
+       /* Create two consecutive PMD mappings for FDT early scan */
+       pa = dtb_pa & ~(PMD_SIZE - 1);
+       create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA,
+                          pa, PMD_SIZE, PAGE_KERNEL);
+       create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE,
+                          pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL);
+       dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1));
+#else
        /* Create two consecutive PGD mappings for FDT early scan */
        pa = dtb_pa & ~(PGDIR_SIZE - 1);
        create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
@@ -501,6 +510,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
        create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE,
                           pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL);
        dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1));
+#endif
        dtb_early_pa = dtb_pa;
 
        /*