mirror of
https://github.com/apache/nuttx.git
synced 2026-09-03 07:33:00 +00:00
riscv: Fix page table traversal for SV39
With CONFIG_PAGING enabled and the RISC-V SV39 MMU active, the page fault handler incorrectly tracked page table levels: `ptprev` pointed to the L1 page table while `ptlevel` indicated L2. This inconsistency caused faulty virtual address resolution. This commit fixes the traversal logic to ensure consistent level tracking across all three page table levels (L1–L3), enabling reliable page fault handling and on-demand paging. Additional changes: - Set PGT_L3_SIZE to 2048 to enable mapping up to 8MB of address space. - Update knsh_paging config to avoid crashes caused by excessive memory alignment requirements. - Add knsh64_paging config to verify this commit works as expected. Signed-off-by: liang.huang <liang.huang@houmo.ai>
This commit is contained in:
parent
82a218cbf3
commit
1653db7ddc
4 changed files with 120 additions and 19 deletions
|
|
@ -207,26 +207,30 @@ int riscv_fillpage(int mcause, void *regs, void *args)
|
|||
}
|
||||
|
||||
satp = READ_CSR(CSR_SATP);
|
||||
ptprev = riscv_pgvaddr(mmu_satp_to_paddr(satp));
|
||||
ptlevel = ARCH_SPGTS;
|
||||
paddr = mmu_pte_to_paddr(mmu_ln_getentry(ptlevel, ptprev, vaddr));
|
||||
if (!paddr)
|
||||
{
|
||||
/* Nothing yet, allocate one page for final level page table */
|
||||
paddr = mmu_satp_to_paddr(satp);
|
||||
|
||||
paddr = mm_pgalloc(1);
|
||||
for (ptlevel = 1; ptlevel <= ARCH_SPGTS; ptlevel++)
|
||||
{
|
||||
ptprev = riscv_pgvaddr(paddr);
|
||||
paddr = mmu_pte_to_paddr(mmu_ln_getentry(ptlevel, ptprev, vaddr));
|
||||
if (!paddr)
|
||||
{
|
||||
return -ENOMEM;
|
||||
/* Nothing yet, allocate one page for next level page table */
|
||||
|
||||
paddr = mm_pgalloc(1);
|
||||
if (!paddr)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Map the page table to the prior level */
|
||||
|
||||
mmu_ln_setentry(ptlevel, ptprev, paddr, vaddr, MMU_UPGT_FLAGS);
|
||||
|
||||
/* This is then used to map the next level */
|
||||
|
||||
riscv_pgwipe(paddr);
|
||||
}
|
||||
|
||||
/* Map the page table to the prior level */
|
||||
|
||||
mmu_ln_setentry(ptlevel, ptprev, paddr, vaddr, MMU_UPGT_FLAGS);
|
||||
|
||||
/* This is then used to map the final level */
|
||||
|
||||
riscv_pgwipe(paddr);
|
||||
}
|
||||
|
||||
ptlast = riscv_pgvaddr(paddr);
|
||||
|
|
@ -242,7 +246,7 @@ int riscv_fillpage(int mcause, void *regs, void *args)
|
|||
|
||||
/* Then map the virtual address to the physical address */
|
||||
|
||||
mmu_ln_setentry(ptlevel + 1, ptlast, paddr, vaddr, mmuflags);
|
||||
mmu_ln_setentry(ARCH_PGT_MAX_LEVELS, ptlast, paddr, vaddr, mmuflags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
#define PGT_L1_SIZE (512) /* Enough to map 512 GiB */
|
||||
#define PGT_L2_SIZE (512) /* Enough to map 1 GiB */
|
||||
#define PGT_L3_SIZE (1024) /* Enough to map 4 MiB (2MiB x 2) */
|
||||
#define PGT_L3_SIZE (2048) /* Enough to map 8 MiB (2MiB x 4) */
|
||||
|
||||
#define SLAB_COUNT (sizeof(m_l3_pgtable) / RV_MMU_PAGE_SIZE)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_ASSERTIONS_FILENAME is not set
|
||||
# CONFIG_DISABLE_OS_API is not set
|
||||
# CONFIG_NDEBUG is not set
|
||||
# CONFIG_NSH_DISABLE_LOSMART is not set
|
||||
CONFIG_16550_ADDRWIDTH=0
|
||||
CONFIG_16550_UART0=y
|
||||
CONFIG_16550_UART0_BASE=0x10000000
|
||||
CONFIG_16550_UART0_CLOCK=3686400
|
||||
CONFIG_16550_UART0_IRQ=35
|
||||
CONFIG_16550_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_16550_UART=y
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_ADDRENV=y
|
||||
CONFIG_ARCH_BOARD="rv-virt"
|
||||
CONFIG_ARCH_BOARD_QEMU_RV_VIRT=y
|
||||
CONFIG_ARCH_CHIP="qemu-rv"
|
||||
CONFIG_ARCH_CHIP_QEMU_RV64=y
|
||||
CONFIG_ARCH_CHIP_QEMU_RV=y
|
||||
CONFIG_ARCH_CHIP_QEMU_RV_ISA_A=y
|
||||
CONFIG_ARCH_CHIP_QEMU_RV_ISA_C=y
|
||||
CONFIG_ARCH_CHIP_QEMU_RV_ISA_M=y
|
||||
CONFIG_ARCH_DATA_NPAGES=128
|
||||
CONFIG_ARCH_DATA_VBASE=0xC0100000
|
||||
CONFIG_ARCH_HEAP_NPAGES=2048
|
||||
CONFIG_ARCH_HEAP_VBASE=0xC0800000
|
||||
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||
CONFIG_ARCH_KERNEL_STACKSIZE=3072
|
||||
CONFIG_ARCH_PGPOOL_MAPPING=y
|
||||
CONFIG_ARCH_PGPOOL_PBASE=0x80a00000
|
||||
CONFIG_ARCH_PGPOOL_SIZE=4194304
|
||||
CONFIG_ARCH_PGPOOL_VBASE=0x80a00000
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_RV_EXT_SSTC=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARCH_TEXT_NPAGES=128
|
||||
CONFIG_ARCH_TEXT_VBASE=0xC0000000
|
||||
CONFIG_ARCH_USE_MMU=y
|
||||
CONFIG_ARCH_USE_MPU=y
|
||||
CONFIG_ARCH_USE_S_MODE=y
|
||||
CONFIG_BINFMT_ELF_EXECUTABLE=y
|
||||
CONFIG_BOARD_INITTHREAD_STACKSIZE=3072
|
||||
CONFIG_BOARD_LATE_INITIALIZE=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=6366
|
||||
CONFIG_BUILD_KERNEL=y
|
||||
CONFIG_DEBUG_FEATURES=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_ELF=y
|
||||
CONFIG_EXAMPLES_HELLO=m
|
||||
CONFIG_EXAMPLES_HELLO_STACKSIZE=8192
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_ROMFS=y
|
||||
CONFIG_GRAN_INTR=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=3072
|
||||
CONFIG_INIT_FILEPATH="/system/bin/init"
|
||||
CONFIG_INIT_MOUNT=y
|
||||
CONFIG_INIT_MOUNT_FLAGS=0x1
|
||||
CONFIG_INIT_MOUNT_TARGET="/system/bin"
|
||||
CONFIG_INIT_STACKSIZE=3072
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_LIBC_ENVPATH=y
|
||||
CONFIG_LIBC_EXECFUNCS=y
|
||||
CONFIG_LIBC_PERROR_STDOUT=y
|
||||
CONFIG_LIBC_STRERROR=y
|
||||
CONFIG_LIBM=y
|
||||
CONFIG_MM_PGALLOC=y
|
||||
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_FILE_APPS=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_PAGING=y
|
||||
CONFIG_PATH_INITIAL="/system/bin"
|
||||
CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE=1048576
|
||||
CONFIG_RAM_SIZE=4194304
|
||||
CONFIG_RAM_START=0x80600000
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SERIAL_UART_ARCH_MMIO=y
|
||||
CONFIG_SIG_DEFAULT=y
|
||||
CONFIG_START_MONTH=12
|
||||
CONFIG_START_YEAR=2021
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
CONFIG_SYSLOG_TIMESTAMP=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYSTEM_NSH_PROGNAME="init"
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_USEC_PER_TICK=1000
|
||||
|
|
@ -94,5 +94,4 @@ CONFIG_SYSTEM_NSH=y
|
|||
CONFIG_SYSTEM_NSH_PROGNAME="init"
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_TLS_LOG2_MAXSTACK=20
|
||||
CONFIG_USEC_PER_TICK=1000
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue