--- /dev/null
+From e112b032a72c78f15d0c803c5dc6be444c2e6c66 Mon Sep 17 00:00:00 2001
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+Date: Fri, 23 Aug 2019 14:24:50 +0800
+Subject: arm64: map FDT as RW for early_init_dt_scan()
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+commit e112b032a72c78f15d0c803c5dc6be444c2e6c66 upstream.
+
+Currently in arm64, FDT is mapped to RO before it's passed to
+early_init_dt_scan(). However, there might be some codes
+(eg. commit "fdt: add support for rng-seed") that need to modify FDT
+during init. Map FDT to RO after early fixups are done.
+
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Mike Rapoport <rppt@linux.ibm.com>
+Signed-off-by: Will Deacon <will@kernel.org>
+[mkbestas: fixed trivial conflicts for 4.14 backport]
+Signed-off-by: Michael Bestas <mkbestas@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/mmu.h | 2 +-
+ arch/arm64/kernel/kaslr.c | 5 +----
+ arch/arm64/kernel/setup.c | 9 ++++++++-
+ arch/arm64/mm/mmu.c | 15 +--------------
+ 4 files changed, 11 insertions(+), 20 deletions(-)
+
+--- a/arch/arm64/include/asm/mmu.h
++++ b/arch/arm64/include/asm/mmu.h
+@@ -91,7 +91,7 @@ extern void init_mem_pgprot(void);
+ extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
+ unsigned long virt, phys_addr_t size,
+ pgprot_t prot, bool page_mappings_only);
+-extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
++extern void *fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot);
+ extern void mark_linear_text_alias_ro(void);
+
+ #endif /* !__ASSEMBLY__ */
+--- a/arch/arm64/kernel/kaslr.c
++++ b/arch/arm64/kernel/kaslr.c
+@@ -65,9 +65,6 @@ out:
+ return default_cmdline;
+ }
+
+-extern void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size,
+- pgprot_t prot);
+-
+ /*
+ * This routine will be executed with the kernel mapped at its default virtual
+ * address, and if it returns successfully, the kernel will be remapped, and
+@@ -96,7 +93,7 @@ u64 __init kaslr_early_init(u64 dt_phys)
+ * attempt at mapping the FDT in setup_machine()
+ */
+ early_fixmap_init();
+- fdt = __fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
++ fdt = fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
+ if (!fdt)
+ return 0;
+
+--- a/arch/arm64/kernel/setup.c
++++ b/arch/arm64/kernel/setup.c
+@@ -179,9 +179,13 @@ static void __init smp_build_mpidr_hash(
+
+ static void __init setup_machine_fdt(phys_addr_t dt_phys)
+ {
+- void *dt_virt = fixmap_remap_fdt(dt_phys);
++ int size;
++ void *dt_virt = fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
+ const char *name;
+
++ if (dt_virt)
++ memblock_reserve(dt_phys, size);
++
+ if (!dt_virt || !early_init_dt_scan(dt_virt)) {
+ pr_crit("\n"
+ "Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
+@@ -193,6 +197,9 @@ static void __init setup_machine_fdt(phy
+ cpu_relax();
+ }
+
++ /* Early fixups are done, map the FDT as read-only now */
++ fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL_RO);
++
+ name = of_flat_dt_get_machine_name();
+ if (!name)
+ return;
+--- a/arch/arm64/mm/mmu.c
++++ b/arch/arm64/mm/mmu.c
+@@ -836,7 +836,7 @@ void __set_fixmap(enum fixed_addresses i
+ }
+ }
+
+-void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
++void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
+ {
+ const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
+ int offset;
+@@ -889,19 +889,6 @@ void *__init __fixmap_remap_fdt(phys_add
+ return dt_virt;
+ }
+
+-void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
+-{
+- void *dt_virt;
+- int size;
+-
+- dt_virt = __fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL_RO);
+- if (!dt_virt)
+- return NULL;
+-
+- memblock_reserve(dt_phys, size);
+- return dt_virt;
+-}
+-
+ int __init arch_ioremap_pud_supported(void)
+ {
+ /*