[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200729233635.14406-4-atish.patra@wdc.com>
Date: Wed, 29 Jul 2020 16:36:29 -0700
From: Atish Patra <atish.patra@....com>
To: linux-kernel@...r.kernel.org
Cc: Atish Patra <atish.patra@....com>, Anup Patel <anup.patel@....com>,
Ard Biesheuvel <ardb@...nel.org>,
Arvind Sankar <nivedita@...m.mit.edu>,
Greentime Hu <greentime.hu@...ive.com>,
Ingo Molnar <mingo@...nel.org>,
Kees Cook <keescook@...omium.org>, linux-efi@...r.kernel.org,
linux-riscv@...ts.infradead.org,
Mark Rutland <mark.rutland@....com>,
Masahiro Yamada <masahiroy@...nel.org>,
Mike Rapoport <rppt@...nel.org>,
Nick Hu <nickhu@...estech.com>,
Palmer Dabbelt <palmer@...belt.com>,
"Paul E. McKenney" <paulmck@...nel.org>,
Paul Walmsley <paul.walmsley@...ive.com>,
Thomas Gleixner <tglx@...utronix.de>,
Will Deacon <will@...nel.org>,
Yash Shah <yash.shah@...ive.com>, Zong Li <zong.li@...ive.com>
Subject: [RFT PATCH v4 3/9] RISC-V: Implement late mapping page table allocation functions
Currently, page table setup is done during setup_va_final where fixmap can
be used to create the temporary mappings. The physical frame is allocated
from memblock_alloc_* functions. However, this won't work if page table
mapping needs to be created for a different mm context (i.e. efi mm) at
a later point of time.
Use generic kernel page allocation function & macros for any mapping
after setup_vm_final.
Signed-off-by: Atish Patra <atish.patra@....com>
---
arch/riscv/mm/init.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 68c608a0e91f..cba03fec08c1 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -212,6 +212,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
static bool mmu_enabled;
+static bool late_mapping;
#define MAX_EARLY_MAPPING_SIZE SZ_128M
@@ -236,7 +237,9 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
static pte_t *__init get_pte_virt(phys_addr_t pa)
{
- if (mmu_enabled) {
+ if (late_mapping)
+ return (pte_t *) __va(pa);
+ else if (mmu_enabled) {
clear_fixmap(FIX_PTE);
return (pte_t *)set_fixmap_offset(FIX_PTE, pa);
} else {
@@ -246,13 +249,19 @@ static pte_t *__init get_pte_virt(phys_addr_t pa)
static phys_addr_t __init alloc_pte(uintptr_t va)
{
+ unsigned long vaddr;
/*
* We only create PMD or PGD early mappings so we
* should never reach here with MMU disabled.
*/
BUG_ON(!mmu_enabled);
-
- return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
+ if (late_mapping) {
+ vaddr = __get_free_page(GFP_KERNEL);
+ if (!vaddr || !pgtable_pte_page_ctor(virt_to_page(vaddr)))
+ BUG();
+ return __pa(vaddr);
+ } else
+ return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
static void __init create_pte_mapping(pte_t *ptep,
@@ -281,7 +290,9 @@ pmd_t early_pmd[PTRS_PER_PMD * NUM_EARLY_PMDS] __initdata __aligned(PAGE_SIZE);
static pmd_t *__init get_pmd_virt(phys_addr_t pa)
{
- if (mmu_enabled) {
+ if (late_mapping)
+ return (pmd_t *) __va(pa);
+ else if (mmu_enabled) {
clear_fixmap(FIX_PMD);
return (pmd_t *)set_fixmap_offset(FIX_PMD, pa);
} else {
@@ -292,8 +303,13 @@ static pmd_t *__init get_pmd_virt(phys_addr_t pa)
static phys_addr_t __init alloc_pmd(uintptr_t va)
{
uintptr_t pmd_num;
+ unsigned long vaddr;
- if (mmu_enabled)
+ if (late_mapping) {
+ vaddr = __get_free_page(GFP_KERNEL);
+ BUG_ON(!vaddr);
+ return __pa(vaddr);
+ } else if (mmu_enabled)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
pmd_num = (va - PAGE_OFFSET) >> PGDIR_SHIFT;
@@ -533,6 +549,9 @@ static void __init setup_vm_final(void)
/* Move to swapper page table */
csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE);
local_flush_tlb_all();
+
+ /* generic page allocation function must be used to setup page table */
+ late_mapping = true;
}
#else
asmlinkage void __init setup_vm(uintptr_t dtb_pa)
--
2.24.0
Powered by blists - more mailing lists