| Kernel-space virtual memory, shared between all processes:
   ____________________________________________________________|___________________________________________________________
                     |            |                  |         |
-   ffffffc6fee00000 | -228    GB | ffffffc6feffffff |    2 MB | fixmap
+   ffffffc6fea00000 | -228    GB | ffffffc6feffffff |    6 MB | fixmap
    ffffffc6ff000000 | -228    GB | ffffffc6ffffffff |   16 MB | PCI io
    ffffffc700000000 | -228    GB | ffffffc7ffffffff |    4 GB | vmemmap
    ffffffc800000000 | -224    GB | ffffffd7ffffffff |   64 GB | vmalloc/ioremap space
                                                               | Kernel-space virtual memory, shared between all processes:
   ____________________________________________________________|___________________________________________________________
                     |            |                  |         |
-   ffff8d7ffee00000 |  -114.5 TB | ffff8d7ffeffffff |    2 MB | fixmap
+   ffff8d7ffea00000 |  -114.5 TB | ffff8d7ffeffffff |    6 MB | fixmap
    ffff8d7fff000000 |  -114.5 TB | ffff8d7fffffffff |   16 MB | PCI io
    ffff8d8000000000 |  -114.5 TB | ffff8f7fffffffff |    2 TB | vmemmap
    ffff8f8000000000 |  -112.5 TB | ffffaf7fffffffff |   32 TB | vmalloc/ioremap space
                                                               | Kernel-space virtual memory, shared between all processes:
   ____________________________________________________________|___________________________________________________________
                     |            |                  |         |
-   ff1bfffffee00000 | -57     PB | ff1bfffffeffffff |    2 MB | fixmap
+   ff1bfffffea00000 | -57     PB | ff1bfffffeffffff |    6 MB | fixmap
    ff1bffffff000000 | -57     PB | ff1bffffffffffff |   16 MB | PCI io
    ff1c000000000000 | -57     PB | ff1fffffffffffff |    1 PB | vmemmap
    ff20000000000000 | -56     PB | ff5fffffffffffff |   16 PB | vmalloc/ioremap space
 
 EXPORT_SYMBOL(empty_zero_page);
 
 extern char _start[];
-#define DTB_EARLY_BASE_VA      PGDIR_SIZE
 void *_dtb_early_va __initdata;
 uintptr_t _dtb_early_pa __initdata;
 
        set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
 
        reserve_initrd_mem();
+
+       /*
+        * No allocation should be done before reserving the memory as defined
+        * in the device tree, otherwise the allocation could end up in a
+        * reserved region.
+        */
+       early_init_fdt_scan_reserved_mem();
+
        /*
         * If DTB is built in, no need to reserve its memblock.
         * Otherwise, do reserve it but avoid using
 static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
 
 pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
-static p4d_t __maybe_unused early_dtb_p4d[PTRS_PER_P4D] __initdata __aligned(PAGE_SIZE);
-static pud_t __maybe_unused early_dtb_pud[PTRS_PER_PUD] __initdata __aligned(PAGE_SIZE);
-static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
 
 #ifdef CONFIG_XIP_KERNEL
 #define pt_ops                 (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops))
 #define trampoline_pgd_next    (pgtable_l5_enabled ?                   \
                (uintptr_t)trampoline_p4d : (pgtable_l4_enabled ?       \
                (uintptr_t)trampoline_pud : (uintptr_t)trampoline_pmd))
-#define early_dtb_pgd_next     (pgtable_l5_enabled ?                   \
-               (uintptr_t)early_dtb_p4d : (pgtable_l4_enabled ?        \
-               (uintptr_t)early_dtb_pud : (uintptr_t)early_dtb_pmd))
 #else
 #define pgd_next_t             pte_t
 #define alloc_pgd_next(__va)   pt_ops.alloc_pte(__va)
 #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot)     \
        create_pte_mapping(__nextp, __va, __pa, __sz, __prot)
 #define fixmap_pgd_next                ((uintptr_t)fixmap_pte)
-#define early_dtb_pgd_next     ((uintptr_t)early_dtb_pmd)
 #define create_p4d_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
 #define create_pud_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
 #define create_pmd_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
  * this means 2 PMD entries whereas for 32-bit kernel, this is only 1 PGDIR
  * entry.
  */
-static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa)
+static void __init create_fdt_early_page_table(pgd_t *pgdir,
+                                              uintptr_t fix_fdt_va,
+                                              uintptr_t dtb_pa)
 {
-#ifndef CONFIG_BUILTIN_DTB
        uintptr_t pa = dtb_pa & ~(PMD_SIZE - 1);
 
-       create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
-                          IS_ENABLED(CONFIG_64BIT) ? early_dtb_pgd_next : pa,
-                          PGDIR_SIZE,
-                          IS_ENABLED(CONFIG_64BIT) ? PAGE_TABLE : PAGE_KERNEL);
-
-       if (pgtable_l5_enabled)
-               create_p4d_mapping(early_dtb_p4d, DTB_EARLY_BASE_VA,
-                                  (uintptr_t)early_dtb_pud, P4D_SIZE, PAGE_TABLE);
-
-       if (pgtable_l4_enabled)
-               create_pud_mapping(early_dtb_pud, DTB_EARLY_BASE_VA,
-                                  (uintptr_t)early_dtb_pmd, PUD_SIZE, PAGE_TABLE);
+#ifndef CONFIG_BUILTIN_DTB
+       /* Make sure the fdt fixmap address is always aligned on PMD size */
+       BUILD_BUG_ON(FIX_FDT % (PMD_SIZE / PAGE_SIZE));
 
-       if (IS_ENABLED(CONFIG_64BIT)) {
-               create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA,
+       /* In 32-bit only, the fdt lies in its own PGD */
+       if (!IS_ENABLED(CONFIG_64BIT)) {
+               create_pgd_mapping(early_pg_dir, fix_fdt_va,
+                                  pa, MAX_FDT_SIZE, PAGE_KERNEL);
+       } else {
+               create_pmd_mapping(fixmap_pmd, fix_fdt_va,
                                   pa, PMD_SIZE, PAGE_KERNEL);
-               create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE,
+               create_pmd_mapping(fixmap_pmd, fix_fdt_va + PMD_SIZE,
                                   pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL);
        }
 
-       dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1));
+       dtb_early_va = (void *)fix_fdt_va + (dtb_pa & (PMD_SIZE - 1));
 #else
        /*
         * For 64-bit kernel, __va can't be used since it would return a linear
        create_kernel_page_table(early_pg_dir, true);
 
        /* Setup early mapping for FDT early scan */
-       create_fdt_early_page_table(early_pg_dir, dtb_pa);
+       create_fdt_early_page_table(early_pg_dir,
+                                   __fix_to_virt(FIX_FDT), dtb_pa);
 
        /*
         * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap
        u64 i;
 
        /* Setup swapper PGD for fixmap */
+#if !defined(CONFIG_64BIT)
+       /*
+        * In 32-bit, the device tree lies in a pgd entry, so it must be copied
+        * directly in swapper_pg_dir in addition to the pgd entry that points
+        * to fixmap_pte.
+        */
+       unsigned long idx = pgd_index(__fix_to_virt(FIX_FDT));
+
+       set_pgd(&swapper_pg_dir[idx], early_pg_dir[idx]);
+#endif
        create_pgd_mapping(swapper_pg_dir, FIXADDR_START,
                           __pa_symbol(fixmap_pgd_next),
                           PGDIR_SIZE, PAGE_TABLE);