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 6a9a835d6f risc-v/mmu: Fix map_region() for incorrect page table setup 
when vaddr is unaligned
6a9a835d6f is described below

commit 6a9a835d6fb6b6c1ea8af430d72e5dc2da07dc69
Author: wushenhui <[email protected]>
AuthorDate: Thu Jun 19 19:52:58 2025 +0800

    risc-v/mmu: Fix map_region() for incorrect page table setup when vaddr is 
unaligned
    
    When the vaddr parameter passed to map_region() is not aligned to the page 
directory,
    it causes incorrect address mapping for later regions.
    
    For example, in the sv32 case, `PGPOOL` started at `0x80a00000` with a size 
of `1024*4096B`,
    leading to page table errors for the range `0x80c00000~0x80e00000`.
    
    This patch fixes the issue by ensuring map_region() correctly handles 
unaligned vaddr cases.
    
    Signed-off-by: wushenhui <[email protected]>
---
 arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c 
b/arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c
index 54c7143587..bc3ab73d51 100644
--- a/arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c
+++ b/arch/risc-v/src/qemu-rv/qemu_rv_mm_init.c
@@ -26,6 +26,7 @@
 
 #include <nuttx/config.h>
 #include <nuttx/arch.h>
+#include <nuttx/nuttx.h>
 
 #include <stdint.h>
 #include <assert.h>
@@ -57,7 +58,8 @@
 #define PGT_L2_VBASE    PGT_L2_PBASE
 
 #define PGT_L1_SIZE     (1024)       /* Enough to map 4 GiB */
-#define PGT_L2_SIZE     (3072)       /* Enough to map 12 MiB */
+#define PGT_L2_SIZE     (4096)       /* Enough to map continuous 12 MiB,
+                                      *  even unaligned */
 
 #define SLAB_COUNT      (sizeof(m_l2_pgtable) / RV_MMU_PAGE_SIZE)
 
@@ -191,18 +193,13 @@ static uintptr_t slab_alloc(void)
 static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
                        uint32_t mmuflags)
 {
+  uintptr_t alignaddr;
   uintptr_t endaddr;
   uintptr_t pbase;
-  int npages;
-  int i;
-  int j;
-
-  /* How many pages */
 
-  npages = (size + RV_MMU_PAGE_MASK) >> RV_MMU_PAGE_SHIFT;
   endaddr = vaddr + size;
 
-  for (i = 0; i < npages; i += RV_MMU_PAGE_ENTRIES)
+  while (vaddr < endaddr)
     {
       /* See if a mapping exists ? */
 
@@ -223,7 +220,8 @@ static void map_region(uintptr_t paddr, uintptr_t vaddr, 
size_t size,
 
       /* Then add the mappings */
 
-      for (j = 0; j < RV_MMU_PAGE_ENTRIES && vaddr < endaddr; j++)
+      alignaddr = ALIGN_UP_MASK(vaddr + 1, RV_MMU_SECTION_ALIGN_MASK);
+      while (vaddr < alignaddr && vaddr < endaddr)
         {
           mmu_ln_setentry(KMM_PBASE_IDX, pbase, paddr, vaddr, mmuflags);
           paddr += KMM_PAGE_SIZE;

Reply via email to