[PATCH v4 2/4] mm: support Svnapot in physical page linear-mapping

Conor.Dooley at microchip.com Conor.Dooley at microchip.com
Mon Aug 22 14:03:11 PDT 2022


Hey, 
Couple questions about some things that caught my eye.
Mostly beyond my pay grade here though...

On 22/08/2022 16:34, panqinglin2020 at iscas.ac.cn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> From: Qinglin Pan <panqinglin2020 at iscas.ac.cn>
> 
> Svnapot is powerful when a physical region is going to mapped to a
> virtual region. Kernel will do like this when mapping all allocable
> physical pages to kernel vm space. This commit modifies the
> create_pte_mapping function used in linear-mapping procedure, so the
> kernel can be able to use Svnapot when both address and length of
> physical region are 64KB align. Code here will be executed only when
> other size huge page is not suitable, so it can be an addition of
> PMD_SIZE and PUD_SIZE mapping.
> 
> This commit also modifies the best_map_size function to give map_size
> many times instead of only once, so a memory region can be mapped by
> both PMD_SIZE and 64KB napot size.
> 
> It is tested by setting qemu's memory to a 262272k region, and the
> kernel can boot successfully.
> 
> Signed-off-by: Qinglin Pan <panqinglin2020 at iscas.ac.cn>
> 
> diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
> index cedcf8ea3c76..395fdc922e9e 100644
> --- a/arch/riscv/include/asm/mmu.h
> +++ b/arch/riscv/include/asm/mmu.h
> @@ -25,6 +25,7 @@ typedef struct {
> 
>  void __init create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa,
>                                phys_addr_t sz, pgprot_t prot);
> +void __init create_linear_mapping(void);
>  #endif /* __ASSEMBLY__ */
> 
>  #endif /* _ASM_RISCV_MMU_H */
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index 95ef6e2bf45c..37e6f7044ef1 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -292,13 +292,16 @@ void __init setup_arch(char **cmdline_p)
>         kasan_init();
>  #endif
> 
> -#ifdef CONFIG_SMP
> -       setup_smp();
> -#endif
> -
>         riscv_fill_hwcap();
>         riscv_init_cbom_blocksize();
>         apply_boot_alternatives();
> +
> +       if (has_svnapot())
> +               create_linear_mapping();

Does this now get called twice if has_svnapot()?
Once here and once in paging_init().

> +
> +#ifdef CONFIG_SMP
> +       setup_smp();
> +#endif

Are there any side effects to moving this down?

>  }
> 
>  static int __init topology_init(void)
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index b56a0a75533f..f54c3991f9ab 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -373,9 +373,21 @@ static void __init create_pte_mapping(pte_t *ptep,
>                                       phys_addr_t sz, pgprot_t prot)
>  {
>         uintptr_t pte_idx = pte_index(va);
> +#ifdef CONFIG_SVNAPOT
> +       pte_t pte;
> +
> +       if (has_svnapot() && sz == NAPOT_CONT64KB_SIZE) {
> +               do {
> +                       pte = pfn_pte(PFN_DOWN(pa), prot);
> +                       ptep[pte_idx] = pte_mknapot(pte, NAPOT_CONT64KB_ORDER);
> +                       pte_idx++;
> +                       sz -= PAGE_SIZE;
> +               } while (sz > 0);
> +               return;
> +       }
> +#endif
> 
>         BUG_ON(sz != PAGE_SIZE);
> -
>         if (pte_none(ptep[pte_idx]))
>                 ptep[pte_idx] = pfn_pte(PFN_DOWN(pa), prot);
>  }
> @@ -673,10 +685,18 @@ void __init create_pgd_mapping(pgd_t *pgdp,
>  static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size)
>  {
>         /* Upgrade to PMD_SIZE mappings whenever possible */
> -       if ((base & (PMD_SIZE - 1)) || (size & (PMD_SIZE - 1)))
> +       base &= PMD_SIZE - 1;
> +       if (!base && size >= PMD_SIZE)
> +               return PMD_SIZE;
> +
> +       if (!has_svnapot())
>                 return PAGE_SIZE;
> 
> -       return PMD_SIZE;
> +       base &= NAPOT_CONT64KB_SIZE - 1;
> +       if (!base && size >= NAPOT_CONT64KB_SIZE)
> +               return NAPOT_CONT64KB_SIZE;
> +
> +       return PAGE_SIZE;
>  }
> 
>  #ifdef CONFIG_XIP_KERNEL
> @@ -1090,18 +1110,12 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
>         pt_ops_set_fixmap();
>  }
> 
> -static void __init setup_vm_final(void)
> +void __init create_linear_mapping(void)
>  {
>         uintptr_t va, map_size;
>         phys_addr_t pa, start, end;
>         u64 i;
> 
> -       /* Setup swapper PGD for fixmap */
> -       create_pgd_mapping(swapper_pg_dir, FIXADDR_START,
> -                          __pa_symbol(fixmap_pgd_next),
> -                          PGDIR_SIZE, PAGE_TABLE);
> -
> -       /* Map all memory banks in the linear mapping */
>         for_each_mem_range(i, &start, &end) {
>                 if (start >= end)
>                         break;
> @@ -1111,14 +1125,25 @@ static void __init setup_vm_final(void)
>                 if (end >= __pa(PAGE_OFFSET) + memory_limit)
>                         end = __pa(PAGE_OFFSET) + memory_limit;
> 
> -               map_size = best_map_size(start, end - start);
>                 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 setup_vm_final(void)
> +{
> +       /* Setup swapper PGD for fixmap */
> +       create_pgd_mapping(swapper_pg_dir, FIXADDR_START,
> +                          __pa_symbol(fixmap_pgd_next),
> +                          PGDIR_SIZE, PAGE_TABLE);
> +
> +       /* Map all memory banks in the linear mapping */
> +       create_linear_mapping();
> 
>         /* Map the kernel */
>         if (IS_ENABLED(CONFIG_64BIT))
> --
> 2.35.1
> 
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv



More information about the linux-riscv mailing list