This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch releases/12.10
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/releases/12.10 by this push:
new 9653e5d6d7 risc-v/mmu: Fix map_region() for incorrect page table setup
when vaddr is unaligned
9653e5d6d7 is described below
commit 9653e5d6d7b23d509990fc40c745696108b86a41
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;