Commit 497fe3bb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'riscv-for-linus-5.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V fix from Palmer Dabbelt:

 - A fix to relocate the DTB early in boot, in cases where the
   bootloader doesn't put the DTB in a region that will end up
   mapped by the kernel.

   This manifests as a crash early in boot on a handful of
   configurations.

* tag 'riscv-for-linus-5.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  RISC-V: relocate DTB if it's outside memory region
parents 4df22ca8 c6fe8119
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -208,8 +208,25 @@ static void __init setup_bootmem(void)
	 * early_init_fdt_reserve_self() since __pa() does
	 * not work for DTB pointers that are fixmap addresses
	 */
	if (!IS_ENABLED(CONFIG_BUILTIN_DTB))
	if (!IS_ENABLED(CONFIG_BUILTIN_DTB)) {
		/*
		 * In case the DTB is not located in a memory region we won't
		 * be able to locate it later on via the linear mapping and
		 * get a segfault when accessing it via __va(dtb_early_pa).
		 * To avoid this situation copy DTB to a memory region.
		 * Note that memblock_phys_alloc will also reserve DTB region.
		 */
		if (!memblock_is_memory(dtb_early_pa)) {
			size_t fdt_size = fdt_totalsize(dtb_early_va);
			phys_addr_t new_dtb_early_pa = memblock_phys_alloc(fdt_size, PAGE_SIZE);
			void *new_dtb_early_va = early_memremap(new_dtb_early_pa, fdt_size);

			memcpy(new_dtb_early_va, dtb_early_va, fdt_size);
			early_memunmap(new_dtb_early_va, fdt_size);
			_dtb_early_pa = new_dtb_early_pa;
		} else
			memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
	}

	early_init_fdt_scan_reserved_mem();
	dma_contiguous_reserve(dma32_phys_limit);