Re: linux-next: manual merge of the risc-v tree with the risc-v-fixes tree

From: Alexandre Ghiti
Date: Thu Apr 20 2023 - 09:24:16 EST


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