Hi, On Thu, Apr 20, 2023 at 2:40 PM <broonie@xxxxxxxxxx> wrote: > > Hi all, > > Today's linux-next merge of the risc-v tree got a conflict in: > > arch/riscv/mm/init.c > > between commit: > > ef69d2559fe91 ("riscv: Move early dtb mapping into the fixmap region") > > from the risc-v-fixes tree and commits: > > 8589e346bbb67 ("riscv: Move the linear mapping creation in its own function") > 3335068f87217 ("riscv: Use PUD/P4D/PGD pages for the linear mapping") > > from the risc-v tree. > > I fixed it up (see below) and can carry the fix as necessary. This > is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. > > diff --cc arch/riscv/mm/init.c > index 0f14f4a8d179a,7bd66795165da..0000000000000 > --- a/arch/riscv/mm/init.c > +++ b/arch/riscv/mm/init.c > @@@ -1070,26 -1112,36 +1092,47 @@@ asmlinkage void __init setup_vm(uintptr > pt_ops_set_fixmap(); > } > > - static void __init setup_vm_final(void) > + static void __init create_linear_mapping_range(phys_addr_t start, > + phys_addr_t end) > { > + phys_addr_t pa; > uintptr_t va, map_size; > - phys_addr_t pa, start, end; > - 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 This does not look correct, fixmap setup should not be in create_linear_mapping_range() function. Please find below the diff I would apply: diff --cc arch/riscv/mm/init.c index 0f14f4a8d179,7bd66795165d..a19146ab9341 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@@ -1070,23 -1112,63 +1092,74 @@@ asmlinkage void __init setup_vm(uintptr pt_ops_set_fixmap(); } - static void __init setup_vm_final(void) + static void __init create_linear_mapping_range(phys_addr_t start, + phys_addr_t end) { + phys_addr_t pa; uintptr_t va, map_size; - phys_addr_t pa, start, end; + + for (pa = start; pa < end; pa += map_size) { + va = (uintptr_t)__va(pa); + map_size = best_map_size(pa, end - pa); + + create_pgd_mapping(swapper_pg_dir, va, pa, map_size, + pgprot_from_va(va)); + } + } + + static void __init create_linear_mapping_page_table(void) + { + phys_addr_t start, end; u64 i; + #ifdef CONFIG_STRICT_KERNEL_RWX + phys_addr_t ktext_start = __pa_symbol(_start); + phys_addr_t ktext_size = __init_data_begin - _start; + phys_addr_t krodata_start = __pa_symbol(__start_rodata); + phys_addr_t krodata_size = _data - __start_rodata; + + /* Isolate kernel text and rodata so they don't get mapped with a PUD */ + memblock_mark_nomap(ktext_start, ktext_size); + memblock_mark_nomap(krodata_start, krodata_size); + #endif + + /* Map all memory banks in the linear mapping */ + for_each_mem_range(i, &start, &end) { + if (start >= end) + break; + if (start <= __pa(PAGE_OFFSET) && + __pa(PAGE_OFFSET) < end) + start = __pa(PAGE_OFFSET); + if (end >= __pa(PAGE_OFFSET) + memory_limit) + end = __pa(PAGE_OFFSET) + memory_limit; + + create_linear_mapping_range(start, end); + } + + #ifdef CONFIG_STRICT_KERNEL_RWX + create_linear_mapping_range(ktext_start, ktext_start + ktext_size); + create_linear_mapping_range(krodata_start, + krodata_start + krodata_size); + + memblock_clear_nomap(ktext_start, ktext_size); + memblock_clear_nomap(krodata_start, krodata_size); + #endif + } + + static void __init setup_vm_final(void) + { /* 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); > - create_pgd_mapping(swapper_pg_dir, FIXADDR_START, > - __pa_symbol(fixmap_pgd_next), > - PGDIR_SIZE, PAGE_TABLE); > ++ > + for (pa = start; pa < end; pa += map_size) { > + va = (uintptr_t)__va(pa); > + map_size = best_map_size(pa, end - pa); > + > + create_pgd_mapping(swapper_pg_dir, va, pa, map_size, > + pgprot_from_va(va)); > + } > + } > + > + static void __init create_linear_mapping_page_table(void) > + { > + phys_addr_t start, end; > + u64 i; > + > + #ifdef CONFIG_STRICT_KERNEL_RWX > + phys_addr_t ktext_start = __pa_symbol(_start); > + phys_addr_t ktext_size = __init_data_begin - _start; > + phys_addr_t krodata_start = __pa_symbol(__start_rodata); > + phys_addr_t krodata_size = _data - __start_rodata; > + > + /* Isolate kernel text and rodata so they don't get mapped with a PUD */ > + memblock_mark_nomap(ktext_start, ktext_size); > + memblock_mark_nomap(krodata_start, krodata_size); > + #endif > > /* Map all memory banks in the linear mapping */ > for_each_mem_range(i, &start, &end) { Thanks! Alex