riscv: mm: Fixup no5lvl failure when vaddr is invalid

Unlike no4lvl, no5lvl still continues to 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: 26e7aacb83 ("riscv: Allow to downgrade paging mode from the command line")
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Björn Töpel <bjorn@rivosinc.com>
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
Tested-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Link: https://patch.msgid.link/20260125055212.433163-1-guoren@kernel.org
[pjw@kernel.org: cleaned up commit message]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
This commit is contained in:
Guo Ren (Alibaba DAMO Academy) 2026-01-25 00:52:12 -05:00 committed by Paul Walmsley
parent 6ebcbb53fc
commit db909bd798

View File

@ -792,6 +792,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
@ -833,6 +854,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 ?
@ -855,6 +879,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);