Merge tag 'riscv-for-linus-5.19-mw0' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / arch / riscv / mm / init.c
index fb599885b3cebd2f42e25d8f8b4eedc53ab88086..eed613599ba67a36490c6c4af13f502718ed75cc 100644 (file)
@@ -120,13 +120,7 @@ void __init mem_init(void)
        BUG_ON(!mem_map);
 #endif /* CONFIG_FLATMEM */
 
-#ifdef CONFIG_SWIOTLB
-       if (swiotlb_force == SWIOTLB_FORCE ||
-           max_pfn > PFN_DOWN(dma32_phys_limit))
-               swiotlb_init(1);
-       else
-               swiotlb_force = SWIOTLB_NO_FORCE;
-#endif
+       swiotlb_init(max_pfn > PFN_DOWN(dma32_phys_limit), SWIOTLB_VERBOSE);
        memblock_free_all();
 
        print_vm_layout();
@@ -208,8 +202,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))
-               memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
+       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);
@@ -718,6 +729,7 @@ retry:
                if (!check_l4) {
                        disable_pgtable_l5();
                        check_l4 = true;
+                       memset(early_pg_dir, 0, PAGE_SIZE);
                        goto retry;
                }
                disable_pgtable_l4();