This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 8a2b83c482 mm/kmap: Finalize kmap implementation for RISC-V
8a2b83c482 is described below

commit 8a2b83c482ad1dc2c3609910a0bd9bef02498eb1
Author: Ville Juven <[email protected]>
AuthorDate: Thu Nov 23 16:25:20 2023 +0200

    mm/kmap: Finalize kmap implementation for RISC-V
    
    After this, RISC-V fully supports the kmap interface.
    
    Due to the current design limitations of having only a single L2 table
    per process, the kernel kmap area cannot be mapped via any user page
    directory, as they do not contain the page tables to address that range.
    
    So a "kernel address environment" is added, which can do the mapping. The
    mapping is reflected to every process as only the root page directory (L1)
    is copied to users, which means every change to L2 / L3 tables will be
    seen by every user.
---
 arch/risc-v/src/common/riscv_addrenv_pgmap.c | 61 +++++++++++++++++++++++++---
 include/nuttx/arch.h                         | 20 +++++++++
 mm/kmap/kmm_map.c                            |  8 +++-
 3 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/arch/risc-v/src/common/riscv_addrenv_pgmap.c 
b/arch/risc-v/src/common/riscv_addrenv_pgmap.c
index edf9687649..da9e250e76 100644
--- a/arch/risc-v/src/common/riscv_addrenv_pgmap.c
+++ b/arch/risc-v/src/common/riscv_addrenv_pgmap.c
@@ -39,6 +39,14 @@
 
 #ifdef CONFIG_BUILD_KERNEL
 
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_MM_KMAP
+static struct arch_addrenv_s g_kernel_addrenv;
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -141,6 +149,51 @@ bool up_addrenv_user_vaddr(uintptr_t vaddr)
 
 #ifdef CONFIG_MM_KMAP
 
+/****************************************************************************
+ * Name: up_addrenv_kmap_init
+ *
+ * Description:
+ *   Initialize the architecture specific part of the kernel mapping
+ *   interface.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+int up_addrenv_kmap_init(void)
+{
+  struct arch_addrenv_s *addrenv;
+  uintptr_t              next;
+  uintptr_t              vaddr;
+  int                    i;
+
+  /* Populate the static page tables one by one */
+
+  addrenv = &g_kernel_addrenv;
+  next    =  g_kernel_pgt_pbase;
+  vaddr   =  CONFIG_ARCH_KMAP_VBASE;
+
+  for (i = 0; i < (ARCH_SPGTS - 1); i++)
+    {
+      /* Connect the static page tables */
+
+      uintptr_t lnvaddr = riscv_pgvaddr(next);
+      addrenv->spgtables[i] = next;
+      next = mmu_pte_to_paddr(mmu_ln_getentry(i + 1, lnvaddr, vaddr));
+    }
+
+  /* Set the page directory root */
+
+  addrenv->satp = mmu_satp_reg(g_kernel_pgt_pbase, 0);
+
+  return OK;
+}
+
 /****************************************************************************
  * Name: up_addrenv_kmap_pages
  *
@@ -164,13 +217,11 @@ bool up_addrenv_user_vaddr(uintptr_t vaddr)
 int up_addrenv_kmap_pages(void **pages, unsigned int npages, uintptr_t vaddr,
                           int prot)
 {
-  struct tcb_s          *tcb     = nxsched_self();
-  struct arch_addrenv_s *addrenv = &tcb->addrenv_own->addrenv;
+  struct arch_addrenv_s *addrenv = &g_kernel_addrenv;
   int mask                       = 0;
 
   /* Sanity checks */
 
-  DEBUGASSERT(tcb && tcb->addrenv_own);
   DEBUGASSERT(pages != NULL && npages > 0);
   DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr < ARCH_KMAP_VEND);
   DEBUGASSERT(MM_ISALIGNED(vaddr));
@@ -220,12 +271,10 @@ int up_addrenv_kmap_pages(void **pages, unsigned int 
npages, uintptr_t vaddr,
 
 int up_addrenv_kunmap_pages(uintptr_t vaddr, unsigned int npages)
 {
-  struct tcb_s          *tcb     = nxsched_self();
-  struct arch_addrenv_s *addrenv = &tcb->addrenv_own->addrenv;
+  struct arch_addrenv_s *addrenv = &g_kernel_addrenv;
 
   /* Sanity checks */
 
-  DEBUGASSERT(tcb && tcb->addrenv_own);
   DEBUGASSERT(npages > 0);
   DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr < ARCH_KMAP_VEND);
   DEBUGASSERT(MM_ISALIGNED(vaddr));
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index 008a56353d..2d65bdc86b 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -1377,6 +1377,26 @@ uintptr_t up_addrenv_page_vaddr(uintptr_t page);
 bool up_addrenv_user_vaddr(uintptr_t vaddr);
 #endif
 
+/****************************************************************************
+ * Name: up_addrenv_kmap_init
+ *
+ * Description:
+ *   Initialize the architecture specific part of the kernel mapping
+ *   interface.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_KMAP)
+int up_addrenv_kmap_init(void);
+#endif
+
 /****************************************************************************
  * Name: up_addrenv_kmap_pages
  *
diff --git a/mm/kmap/kmm_map.c b/mm/kmap/kmm_map.c
index cb270706f1..bcd8fbb14d 100644
--- a/mm/kmap/kmm_map.c
+++ b/mm/kmap/kmm_map.c
@@ -279,10 +279,16 @@ static void kmm_map_unlock(void)
 
 void kmm_map_initialize(void)
 {
+  /* Initialize the architecture specific part */
+
+  DEBUGVERIFY(up_addrenv_kmap_init());
+
+  /* Then, the local vmap */
+
   g_kmm_map_vpages = gran_initialize((FAR void *)CONFIG_ARCH_KMAP_VBASE,
                                      CONFIG_ARCH_KMAP_NPAGES << MM_PGSHIFT,
                                      MM_PGSHIFT, MM_PGSHIFT);
-  DEBUGVERIFY(g_kmm_map_vpages);
+  DEBUGASSERT(g_kmm_map_vpages != NULL);
   mm_map_initialize(&g_kmm_map, true);
 }
 

Reply via email to