riscv: Introduce functions to switch pt_ops
authorAlexandre Ghiti <alexandre.ghiti@canonical.com>
Mon, 6 Dec 2021 10:46:47 +0000 (11:46 +0100)
committerPalmer Dabbelt <palmer@rivosinc.com>
Thu, 20 Jan 2022 01:54:06 +0000 (17:54 -0800)
This simply gathers the different pt_ops initialization in functions
where a comment was added to explain why the page table operations must
be changed along the boot process.

Signed-off-by: Alexandre Ghiti <alexandre.ghiti@canonical.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/mm/init.c

index f5d0052..424d777 100644 (file)
@@ -581,6 +581,52 @@ static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa)
        dtb_early_pa = dtb_pa;
 }
 
+/*
+ * MMU is not enabled, the page tables are allocated directly using
+ * early_pmd/pud/p4d and the address returned is the physical one.
+ */
+void pt_ops_set_early(void)
+{
+       pt_ops.alloc_pte = alloc_pte_early;
+       pt_ops.get_pte_virt = get_pte_virt_early;
+#ifndef __PAGETABLE_PMD_FOLDED
+       pt_ops.alloc_pmd = alloc_pmd_early;
+       pt_ops.get_pmd_virt = get_pmd_virt_early;
+#endif
+}
+
+/*
+ * MMU is enabled but page table setup is not complete yet.
+ * fixmap page table alloc functions must be used as a means to temporarily
+ * map the allocated physical pages since the linear mapping does not exist yet.
+ *
+ * Note that this is called with MMU disabled, hence kernel_mapping_pa_to_va,
+ * but it will be used as described above.
+ */
+void pt_ops_set_fixmap(void)
+{
+       pt_ops.alloc_pte = kernel_mapping_pa_to_va((uintptr_t)alloc_pte_fixmap);
+       pt_ops.get_pte_virt = kernel_mapping_pa_to_va((uintptr_t)get_pte_virt_fixmap);
+#ifndef __PAGETABLE_PMD_FOLDED
+       pt_ops.alloc_pmd = kernel_mapping_pa_to_va((uintptr_t)alloc_pmd_fixmap);
+       pt_ops.get_pmd_virt = kernel_mapping_pa_to_va((uintptr_t)get_pmd_virt_fixmap);
+#endif
+}
+
+/*
+ * MMU is enabled and page table setup is complete, so from now, we can use
+ * generic page allocation functions to setup page table.
+ */
+void pt_ops_set_late(void)
+{
+       pt_ops.alloc_pte = alloc_pte_late;
+       pt_ops.get_pte_virt = get_pte_virt_late;
+#ifndef __PAGETABLE_PMD_FOLDED
+       pt_ops.alloc_pmd = alloc_pmd_late;
+       pt_ops.get_pmd_virt = get_pmd_virt_late;
+#endif
+}
+
 asmlinkage void __init setup_vm(uintptr_t dtb_pa)
 {
        pmd_t __maybe_unused fix_bmap_spmd, fix_bmap_epmd;
@@ -625,12 +671,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
        BUG_ON((kernel_map.virt_addr + kernel_map.size) > ADDRESS_SPACE_END - SZ_4K);
 #endif
 
-       pt_ops.alloc_pte = alloc_pte_early;
-       pt_ops.get_pte_virt = get_pte_virt_early;
-#ifndef __PAGETABLE_PMD_FOLDED
-       pt_ops.alloc_pmd = alloc_pmd_early;
-       pt_ops.get_pmd_virt = get_pmd_virt_early;
-#endif
+       pt_ops_set_early();
+
        /* Setup early PGD for fixmap */
        create_pgd_mapping(early_pg_dir, FIXADDR_START,
                           (uintptr_t)fixmap_pgd_next, PGDIR_SIZE, PAGE_TABLE);
@@ -694,6 +736,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
                pr_warn("FIX_BTMAP_BEGIN:     %d\n", FIX_BTMAP_BEGIN);
        }
 #endif
+
+       pt_ops_set_fixmap();
 }
 
 static void __init setup_vm_final(void)
@@ -702,16 +746,6 @@ static void __init setup_vm_final(void)
        phys_addr_t pa, start, end;
        u64 i;
 
-       /**
-        * MMU is enabled at this point. But page table setup is not complete yet.
-        * fixmap page table alloc functions should be used at this point
-        */
-       pt_ops.alloc_pte = alloc_pte_fixmap;
-       pt_ops.get_pte_virt = get_pte_virt_fixmap;
-#ifndef __PAGETABLE_PMD_FOLDED
-       pt_ops.alloc_pmd = alloc_pmd_fixmap;
-       pt_ops.get_pmd_virt = get_pmd_virt_fixmap;
-#endif
        /* Setup swapper PGD for fixmap */
        create_pgd_mapping(swapper_pg_dir, FIXADDR_START,
                           __pa_symbol(fixmap_pgd_next),
@@ -753,13 +787,7 @@ static void __init setup_vm_final(void)
        csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE);
        local_flush_tlb_all();
 
-       /* generic page allocation functions must be used to setup page table */
-       pt_ops.alloc_pte = alloc_pte_late;
-       pt_ops.get_pte_virt = get_pte_virt_late;
-#ifndef __PAGETABLE_PMD_FOLDED
-       pt_ops.alloc_pmd = alloc_pmd_late;
-       pt_ops.get_pmd_virt = get_pmd_virt_late;
-#endif
+       pt_ops_set_late();
 }
 #else
 asmlinkage void __init setup_vm(uintptr_t dtb_pa)