diff --git a/arch/risc-v/src/common/riscv_addrenv_utils.c b/arch/risc-v/src/common/riscv_addrenv_utils.c index 810563aedd4..e13fb89ff9e 100644 --- a/arch/risc-v/src/common/riscv_addrenv_utils.c +++ b/arch/risc-v/src/common/riscv_addrenv_utils.c @@ -63,13 +63,22 @@ uintptr_t riscv_get_pgtable(arch_addrenv_t *addrenv, uintptr_t vaddr) uintptr_t paddr; uintptr_t ptprev; uint32_t ptlevel; + uint32_t flags; /* Get the current level MAX_LEVELS-1 entry corresponding to this vaddr */ ptlevel = ARCH_SPGTS; ptprev = riscv_pgvaddr(addrenv->spgtables[ARCH_SPGTS - 1]); - paddr = mmu_pte_to_paddr(mmu_ln_getentry(ptlevel, ptprev, vaddr)); + if (!ptprev) + { + /* Something is very wrong */ + return 0; + } + + /* Find the physical address of the final level page table */ + + paddr = mmu_pte_to_paddr(mmu_ln_getentry(ptlevel, ptprev, vaddr)); if (!paddr) { /* No page table has been allocated... allocate one now */ @@ -77,10 +86,21 @@ uintptr_t riscv_get_pgtable(arch_addrenv_t *addrenv, uintptr_t vaddr) paddr = mm_pgalloc(1); if (paddr) { + /* Determine page table flags */ + + if (riscv_uservaddr(vaddr)) + { + flags = MMU_UPGT_FLAGS; + } + else + { + flags = MMU_KPGT_FLAGS; + } + /* Wipe the page and assign it */ riscv_pgwipe(paddr); - mmu_ln_setentry(ptlevel, ptprev, paddr, vaddr, MMU_UPGT_FLAGS); + mmu_ln_setentry(ptlevel, ptprev, paddr, vaddr, flags); } } diff --git a/arch/risc-v/src/common/riscv_mmu.h b/arch/risc-v/src/common/riscv_mmu.h index 0c0c6b53737..6c9d1baebb9 100644 --- a/arch/risc-v/src/common/riscv_mmu.h +++ b/arch/risc-v/src/common/riscv_mmu.h @@ -59,6 +59,10 @@ #define MMU_IO_FLAGS (PTE_R | PTE_W | PTE_G) +/* Flags for kernel page tables */ + +#define MMU_KPGT_FLAGS (PTE_G) + /* Kernel FLASH and RAM are mapped globally */ #define MMU_KTEXT_FLAGS (PTE_R | PTE_X | PTE_G)