[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