>From: "Guo Ren (Alibaba DAMO Academy)" > >Unlike no4lvl, no5lvl still continues detect satp, which >requires va=pa mapping. When pa=0x800000000000, no5lvl >would fail in Sv48 mode due to an illegal VA value of >0x800000000000. > >So, prevent detecting the satp flow for no5lvl, when >vaddr is invalid. Add the is_vaddr_valid() function for >checking. > >Fixes: 26e7aacb83df ("riscv: Allow to downgrade paging mode from the command line") >Cc: Alexandre Ghiti >Cc: Björn Töpel >Signed-off-by: Guo Ren (Alibaba DAMO Academy) >--- >Changelog: > >v2: > - Use is_vaddr_valid() instead of simple return. > - Don't change the original no5lvl code logic. > >v1: >https://lore.kernel.org/linux-riscv/20260118145441.291302-1-guoren@kernel.org/ >--- > arch/riscv/mm/init.c | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > >diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c >index addb8a9305be..bfea9f73e703 100644 >--- a/arch/riscv/mm/init.c >+++ b/arch/riscv/mm/init.c >@@ -852,6 +852,27 @@ static void __init set_mmap_rnd_bits_max(void) > mmap_rnd_bits_max = MMAP_VA_BITS - PAGE_SHIFT - 3; > } > >+static bool __init is_vaddr_valid(unsigned long va) >+{ >+ unsigned long up = 0; >+ >+ switch (satp_mode) { >+ case SATP_MODE_39: >+ up = 1UL << 38; >+ break; >+ case SATP_MODE_48: >+ up = 1UL << 47; >+ break; >+ case SATP_MODE_57: >+ up = 1UL << 56; >+ break; >+ default: >+ return false; >+ } >+ >+ return (va < up) || (va >= (ULONG_MAX - up + 1)); >+} >+ > /* > * There is a simple way to determine if 4-level is supported by the > * underlying hardware: establish 1:1 mapping in 4-level page table mode >@@ -893,6 +914,9 @@ static __init void set_satp_mode(uintptr_t dtb_pa) > set_satp_mode_pmd + PMD_SIZE, > PMD_SIZE, PAGE_KERNEL_EXEC); > retry: >+ if (!is_vaddr_valid(set_satp_mode_pmd)) >+ goto out; >+ > create_pgd_mapping(early_pg_dir, > set_satp_mode_pmd, > pgtable_l5_enabled ? >@@ -915,6 +939,7 @@ static __init void set_satp_mode(uintptr_t dtb_pa) > disable_pgtable_l4(); > } > >+out: > memset(early_pg_dir, 0, PAGE_SIZE); > memset(early_p4d, 0, PAGE_SIZE); > memset(early_pud, 0, PAGE_SIZE); >-- >2.40.1 Tested on hardware where DRAM/PA starts at 0x800000000000. With "no5lvl" on the kernel command line, the kernel boots successfully after this patch. Tested-by: Fangyu Yu Thanks, Fangyu