* [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit @ 2025-07-21 16:53 Junhui Liu 2025-07-21 16:53 ` [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options Junhui Liu ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Junhui Liu @ 2025-07-21 16:53 UTC (permalink / raw) To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti Cc: linux-riscv, linux-kernel, Junhui Liu This patch series improves RISC-V kernel compatibility and robustness by refining how the SATP mode is determined during early boot. Some RISC-V implementations, such as the Anlogic DR1V90 FPSoC with a UX900 RISC-V core designed by Nuclei, which I am currently attempting to run the mainline kernel on [1], may hang when attempting to write an unsupported SATP mode. To address this, the patch determines the SATP mode limit by taking the minimum of the value specified by the kernel command line option ("noXlvl", e.g., "no4lvl" or "no5lvl") and the "mmu-type" property in the device tree for the first enabled CPU. If only one is specified, that value will be used as the limit. - If the resulting SATP mode limit is sv48 or higher, the kernel will probe SATP modes from this limit down to lower modes until a supported mode is found. - If the limit is sv39, the kernel will directly use sv39 without probing lower modes. Link: https://lore.kernel.org/r/20250721-dr1v90-basic-dt-v1-0-5740c5199c47@pigmoral.tech [1] --- Junhui Liu (2): riscv: mm: Return intended SATP mode for noXlvl options riscv: mm: Use mmu-type from FDT to limit SATP mode arch/riscv/kernel/pi/cmdline_early.c | 4 ++-- arch/riscv/kernel/pi/fdt_early.c | 40 ++++++++++++++++++++++++++++++++++++ arch/riscv/kernel/pi/pi.h | 1 + arch/riscv/mm/init.c | 11 +++++++--- 4 files changed, 51 insertions(+), 5 deletions(-) --- base-commit: 89be9a83ccf1f88522317ce02f854f30d6115c41 change-id: 20250713-satp-from-fdt-c22c245c27e9 Best regards, -- Junhui Liu <junhui.liu@pigmoral.tech> _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options 2025-07-21 16:53 [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit Junhui Liu @ 2025-07-21 16:53 ` Junhui Liu 2025-07-22 4:33 ` Nutty Liu 2025-07-25 14:02 ` Alexandre Ghiti 2025-07-21 16:53 ` [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode Junhui Liu 2025-08-06 17:15 ` [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit patchwork-bot+linux-riscv 2 siblings, 2 replies; 9+ messages in thread From: Junhui Liu @ 2025-07-21 16:53 UTC (permalink / raw) To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti Cc: linux-riscv, linux-kernel, Junhui Liu Change the return value of match_noXlvl() to return the SATP mode that will be used, rather than the mode being disabled. This enables unified logic for return value judgement with the function that obtains mmu-type from the fdt, avoiding extra conversion. This only changes the naming, with no functional impact. Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> --- arch/riscv/kernel/pi/cmdline_early.c | 4 ++-- arch/riscv/mm/init.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/riscv/kernel/pi/cmdline_early.c b/arch/riscv/kernel/pi/cmdline_early.c index fbcdc9e4e14322af0cedd31343aeb9403ba2dd14..389d086a071876dde2fd57ee6f6661e65c38b7c4 100644 --- a/arch/riscv/kernel/pi/cmdline_early.c +++ b/arch/riscv/kernel/pi/cmdline_early.c @@ -41,9 +41,9 @@ static char *get_early_cmdline(uintptr_t dtb_pa) static u64 match_noXlvl(char *cmdline) { if (strstr(cmdline, "no4lvl")) - return SATP_MODE_48; + return SATP_MODE_39; else if (strstr(cmdline, "no5lvl")) - return SATP_MODE_57; + return SATP_MODE_48; return 0; } diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 8d0374d7ce8ed72320f58e4cea212d0e2bce8fd4..d03e02a92379f2338a4f4df0ab797a7859b83dfc 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -864,9 +864,9 @@ static __init void set_satp_mode(uintptr_t dtb_pa) kernel_map.page_offset = PAGE_OFFSET_L5; - if (satp_mode_cmdline == SATP_MODE_57) { + if (satp_mode_cmdline == SATP_MODE_48) { disable_pgtable_l5(); - } else if (satp_mode_cmdline == SATP_MODE_48) { + } else if (satp_mode_cmdline == SATP_MODE_39) { disable_pgtable_l5(); disable_pgtable_l4(); return; -- 2.50.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options 2025-07-21 16:53 ` [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options Junhui Liu @ 2025-07-22 4:33 ` Nutty Liu 2025-07-25 14:02 ` Alexandre Ghiti 1 sibling, 0 replies; 9+ messages in thread From: Nutty Liu @ 2025-07-22 4:33 UTC (permalink / raw) To: Junhui Liu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti Cc: linux-riscv, linux-kernel On 7/22/2025 12:53 AM, Junhui Liu wrote: > Change the return value of match_noXlvl() to return the SATP mode that > will be used, rather than the mode being disabled. This enables unified > logic for return value judgement with the function that obtains mmu-type > from the fdt, avoiding extra conversion. This only changes the naming, > with no functional impact. > > Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> > --- > arch/riscv/kernel/pi/cmdline_early.c | 4 ++-- > arch/riscv/mm/init.c | 4 ++-- > 2 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/arch/riscv/kernel/pi/cmdline_early.c b/arch/riscv/kernel/pi/cmdline_early.c > index fbcdc9e4e14322af0cedd31343aeb9403ba2dd14..389d086a071876dde2fd57ee6f6661e65c38b7c4 100644 > --- a/arch/riscv/kernel/pi/cmdline_early.c > +++ b/arch/riscv/kernel/pi/cmdline_early.c > @@ -41,9 +41,9 @@ static char *get_early_cmdline(uintptr_t dtb_pa) > static u64 match_noXlvl(char *cmdline) > { > if (strstr(cmdline, "no4lvl")) > - return SATP_MODE_48; > + return SATP_MODE_39; > else if (strstr(cmdline, "no5lvl")) > - return SATP_MODE_57; > + return SATP_MODE_48; > > return 0; > } > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c > index 8d0374d7ce8ed72320f58e4cea212d0e2bce8fd4..d03e02a92379f2338a4f4df0ab797a7859b83dfc 100644 > --- a/arch/riscv/mm/init.c > +++ b/arch/riscv/mm/init.c > @@ -864,9 +864,9 @@ static __init void set_satp_mode(uintptr_t dtb_pa) > > kernel_map.page_offset = PAGE_OFFSET_L5; > > - if (satp_mode_cmdline == SATP_MODE_57) { > + if (satp_mode_cmdline == SATP_MODE_48) { > disable_pgtable_l5(); > - } else if (satp_mode_cmdline == SATP_MODE_48) { > + } else if (satp_mode_cmdline == SATP_MODE_39) { > disable_pgtable_l5(); > disable_pgtable_l4(); > return; Nice, this change is a good idea. It's more readable. Reviewed-by: Nutty Liu <liujingqi@lanxincomputing.com> Thanks, Nutty _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options 2025-07-21 16:53 ` [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options Junhui Liu 2025-07-22 4:33 ` Nutty Liu @ 2025-07-25 14:02 ` Alexandre Ghiti 1 sibling, 0 replies; 9+ messages in thread From: Alexandre Ghiti @ 2025-07-25 14:02 UTC (permalink / raw) To: Junhui Liu, Paul Walmsley, Palmer Dabbelt, Albert Ou Cc: linux-riscv, linux-kernel Hi Junhui, On 7/21/25 18:53, Junhui Liu wrote: > Change the return value of match_noXlvl() to return the SATP mode that > will be used, rather than the mode being disabled. This enables unified > logic for return value judgement with the function that obtains mmu-type > from the fdt, avoiding extra conversion. This only changes the naming, > with no functional impact. > > Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> > --- > arch/riscv/kernel/pi/cmdline_early.c | 4 ++-- > arch/riscv/mm/init.c | 4 ++-- > 2 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/arch/riscv/kernel/pi/cmdline_early.c b/arch/riscv/kernel/pi/cmdline_early.c > index fbcdc9e4e14322af0cedd31343aeb9403ba2dd14..389d086a071876dde2fd57ee6f6661e65c38b7c4 100644 > --- a/arch/riscv/kernel/pi/cmdline_early.c > +++ b/arch/riscv/kernel/pi/cmdline_early.c > @@ -41,9 +41,9 @@ static char *get_early_cmdline(uintptr_t dtb_pa) > static u64 match_noXlvl(char *cmdline) > { > if (strstr(cmdline, "no4lvl")) > - return SATP_MODE_48; > + return SATP_MODE_39; > else if (strstr(cmdline, "no5lvl")) > - return SATP_MODE_57; > + return SATP_MODE_48; > > return 0; > } > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c > index 8d0374d7ce8ed72320f58e4cea212d0e2bce8fd4..d03e02a92379f2338a4f4df0ab797a7859b83dfc 100644 > --- a/arch/riscv/mm/init.c > +++ b/arch/riscv/mm/init.c > @@ -864,9 +864,9 @@ static __init void set_satp_mode(uintptr_t dtb_pa) > > kernel_map.page_offset = PAGE_OFFSET_L5; > > - if (satp_mode_cmdline == SATP_MODE_57) { > + if (satp_mode_cmdline == SATP_MODE_48) { > disable_pgtable_l5(); > - } else if (satp_mode_cmdline == SATP_MODE_48) { > + } else if (satp_mode_cmdline == SATP_MODE_39) { > disable_pgtable_l5(); > disable_pgtable_l4(); > return; > Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com> Thanks, Alex _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode 2025-07-21 16:53 [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit Junhui Liu 2025-07-21 16:53 ` [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options Junhui Liu @ 2025-07-21 16:53 ` Junhui Liu 2025-07-22 4:36 ` Nutty Liu 2025-07-25 14:04 ` Alexandre Ghiti 2025-08-06 17:15 ` [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit patchwork-bot+linux-riscv 2 siblings, 2 replies; 9+ messages in thread From: Junhui Liu @ 2025-07-21 16:53 UTC (permalink / raw) To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti Cc: linux-riscv, linux-kernel, Junhui Liu Some RISC-V implementations may hang when attempting to write an unsupported SATP mode, even though the latest RISC-V specification states such writes should have no effect. To avoid this issue, the logic for selecting SATP mode has been refined: The kernel now determines the SATP mode limit by taking the minimum of the value specified by the kernel command line (noXlvl) and the "mmu-type" property in the device tree (FDT). If only one is specified, use that. - If the resulting limit is sv48 or higher, the kernel will probe SATP modes from this limit downward until a supported mode is found. - If the limit is sv39, the kernel will directly use sv39 without probing. This ensures SATP mode selection is safe and compatible with both hardware and user configuration, minimizing the risk of hangs. Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> --- arch/riscv/kernel/pi/fdt_early.c | 40 ++++++++++++++++++++++++++++++++++++++++ arch/riscv/kernel/pi/pi.h | 1 + arch/riscv/mm/init.c | 11 ++++++++--- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/arch/riscv/kernel/pi/fdt_early.c b/arch/riscv/kernel/pi/fdt_early.c index 9bdee2fafe47e4a889132ebe2d0d360717c464e9..a12ff8090f190331f555d9e22ce4d1b3e940bceb 100644 --- a/arch/riscv/kernel/pi/fdt_early.c +++ b/arch/riscv/kernel/pi/fdt_early.c @@ -3,6 +3,7 @@ #include <linux/init.h> #include <linux/libfdt.h> #include <linux/ctype.h> +#include <asm/csr.h> #include "pi.h" @@ -183,3 +184,42 @@ bool fdt_early_match_extension_isa(const void *fdt, const char *ext_name) return ret; } + +/** + * set_satp_mode_from_fdt - determine SATP mode based on the MMU type in fdt + * + * @dtb_pa: physical address of the device tree blob + * + * Returns the SATP mode corresponding to the MMU type of the first enabled CPU, + * 0 otherwise + */ +u64 set_satp_mode_from_fdt(uintptr_t dtb_pa) +{ + const void *fdt = (const void *)dtb_pa; + const char *mmu_type; + int node, parent; + + parent = fdt_path_offset(fdt, "/cpus"); + if (parent < 0) + return 0; + + fdt_for_each_subnode(node, fdt, parent) { + if (!fdt_node_name_eq(fdt, node, "cpu")) + continue; + + if (!fdt_device_is_available(fdt, node)) + continue; + + mmu_type = fdt_getprop(fdt, node, "mmu-type", NULL); + if (!mmu_type) + break; + + if (!strcmp(mmu_type, "riscv,sv39")) + return SATP_MODE_39; + else if (!strcmp(mmu_type, "riscv,sv48")) + return SATP_MODE_48; + break; + } + + return 0; +} diff --git a/arch/riscv/kernel/pi/pi.h b/arch/riscv/kernel/pi/pi.h index 21141d84fea603fdfc439e12a8c3216f1527c65f..3fee2cfddf7cfb8179af6f2d9b69a0d5e412fad7 100644 --- a/arch/riscv/kernel/pi/pi.h +++ b/arch/riscv/kernel/pi/pi.h @@ -14,6 +14,7 @@ u64 get_kaslr_seed(uintptr_t dtb_pa); u64 get_kaslr_seed_zkr(const uintptr_t dtb_pa); bool set_nokaslr_from_cmdline(uintptr_t dtb_pa); u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa); +u64 set_satp_mode_from_fdt(uintptr_t dtb_pa); bool fdt_early_match_extension_isa(const void *fdt, const char *ext_name); diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index d03e02a92379f2338a4f4df0ab797a7859b83dfc..0f30fa875abf92a201579ac6469958b0d95b5a58 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -816,6 +816,7 @@ static __meminit pgprot_t pgprot_from_va(uintptr_t va) #if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL) u64 __pi_set_satp_mode_from_cmdline(uintptr_t dtb_pa); +u64 __pi_set_satp_mode_from_fdt(uintptr_t dtb_pa); static void __init disable_pgtable_l5(void) { @@ -855,18 +856,22 @@ static void __init set_mmap_rnd_bits_max(void) * underlying hardware: establish 1:1 mapping in 4-level page table mode * then read SATP to see if the configuration was taken into account * meaning sv48 is supported. + * The maximum SATP mode is limited by both the command line and the "mmu-type" + * property in the device tree, since some platforms may hang if an unsupported + * SATP mode is attempted. */ static __init void set_satp_mode(uintptr_t dtb_pa) { u64 identity_satp, hw_satp; uintptr_t set_satp_mode_pmd = ((unsigned long)set_satp_mode) & PMD_MASK; - u64 satp_mode_cmdline = __pi_set_satp_mode_from_cmdline(dtb_pa); + u64 satp_mode_limit = min_not_zero(__pi_set_satp_mode_from_cmdline(dtb_pa), + __pi_set_satp_mode_from_fdt(dtb_pa)); kernel_map.page_offset = PAGE_OFFSET_L5; - if (satp_mode_cmdline == SATP_MODE_48) { + if (satp_mode_limit == SATP_MODE_48) { disable_pgtable_l5(); - } else if (satp_mode_cmdline == SATP_MODE_39) { + } else if (satp_mode_limit == SATP_MODE_39) { disable_pgtable_l5(); disable_pgtable_l4(); return; -- 2.50.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode 2025-07-21 16:53 ` [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode Junhui Liu @ 2025-07-22 4:36 ` Nutty Liu 2025-07-25 14:04 ` Alexandre Ghiti 1 sibling, 0 replies; 9+ messages in thread From: Nutty Liu @ 2025-07-22 4:36 UTC (permalink / raw) To: Junhui Liu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti Cc: linux-riscv, linux-kernel On 7/22/2025 12:53 AM, Junhui Liu wrote: > Some RISC-V implementations may hang when attempting to write an > unsupported SATP mode, even though the latest RISC-V specification > states such writes should have no effect. To avoid this issue, the > logic for selecting SATP mode has been refined: > > The kernel now determines the SATP mode limit by taking the minimum of > the value specified by the kernel command line (noXlvl) and the > "mmu-type" property in the device tree (FDT). If only one is specified, > use that. > - If the resulting limit is sv48 or higher, the kernel will probe SATP > modes from this limit downward until a supported mode is found. > - If the limit is sv39, the kernel will directly use sv39 without > probing. > > This ensures SATP mode selection is safe and compatible with both > hardware and user configuration, minimizing the risk of hangs. > > Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> > --- > arch/riscv/kernel/pi/fdt_early.c | 40 ++++++++++++++++++++++++++++++++++++++++ > arch/riscv/kernel/pi/pi.h | 1 + > arch/riscv/mm/init.c | 11 ++++++++--- > 3 files changed, 49 insertions(+), 3 deletions(-) Reviewed-by: Nutty Liu <liujingqi@lanxincomputing.com> Thanks, Nutty > > diff --git a/arch/riscv/kernel/pi/fdt_early.c b/arch/riscv/kernel/pi/fdt_early.c > index 9bdee2fafe47e4a889132ebe2d0d360717c464e9..a12ff8090f190331f555d9e22ce4d1b3e940bceb 100644 > --- a/arch/riscv/kernel/pi/fdt_early.c > +++ b/arch/riscv/kernel/pi/fdt_early.c > @@ -3,6 +3,7 @@ > #include <linux/init.h> > #include <linux/libfdt.h> > #include <linux/ctype.h> > +#include <asm/csr.h> > > #include "pi.h" > > @@ -183,3 +184,42 @@ bool fdt_early_match_extension_isa(const void *fdt, const char *ext_name) > > return ret; > } > + > +/** > + * set_satp_mode_from_fdt - determine SATP mode based on the MMU type in fdt > + * > + * @dtb_pa: physical address of the device tree blob > + * > + * Returns the SATP mode corresponding to the MMU type of the first enabled CPU, > + * 0 otherwise > + */ > +u64 set_satp_mode_from_fdt(uintptr_t dtb_pa) > +{ > + const void *fdt = (const void *)dtb_pa; > + const char *mmu_type; > + int node, parent; > + > + parent = fdt_path_offset(fdt, "/cpus"); > + if (parent < 0) > + return 0; > + > + fdt_for_each_subnode(node, fdt, parent) { > + if (!fdt_node_name_eq(fdt, node, "cpu")) > + continue; > + > + if (!fdt_device_is_available(fdt, node)) > + continue; > + > + mmu_type = fdt_getprop(fdt, node, "mmu-type", NULL); > + if (!mmu_type) > + break; > + > + if (!strcmp(mmu_type, "riscv,sv39")) > + return SATP_MODE_39; > + else if (!strcmp(mmu_type, "riscv,sv48")) > + return SATP_MODE_48; > + break; > + } > + > + return 0; > +} > diff --git a/arch/riscv/kernel/pi/pi.h b/arch/riscv/kernel/pi/pi.h > index 21141d84fea603fdfc439e12a8c3216f1527c65f..3fee2cfddf7cfb8179af6f2d9b69a0d5e412fad7 100644 > --- a/arch/riscv/kernel/pi/pi.h > +++ b/arch/riscv/kernel/pi/pi.h > @@ -14,6 +14,7 @@ u64 get_kaslr_seed(uintptr_t dtb_pa); > u64 get_kaslr_seed_zkr(const uintptr_t dtb_pa); > bool set_nokaslr_from_cmdline(uintptr_t dtb_pa); > u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa); > +u64 set_satp_mode_from_fdt(uintptr_t dtb_pa); > > bool fdt_early_match_extension_isa(const void *fdt, const char *ext_name); > > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c > index d03e02a92379f2338a4f4df0ab797a7859b83dfc..0f30fa875abf92a201579ac6469958b0d95b5a58 100644 > --- a/arch/riscv/mm/init.c > +++ b/arch/riscv/mm/init.c > @@ -816,6 +816,7 @@ static __meminit pgprot_t pgprot_from_va(uintptr_t va) > > #if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL) > u64 __pi_set_satp_mode_from_cmdline(uintptr_t dtb_pa); > +u64 __pi_set_satp_mode_from_fdt(uintptr_t dtb_pa); > > static void __init disable_pgtable_l5(void) > { > @@ -855,18 +856,22 @@ static void __init set_mmap_rnd_bits_max(void) > * underlying hardware: establish 1:1 mapping in 4-level page table mode > * then read SATP to see if the configuration was taken into account > * meaning sv48 is supported. > + * The maximum SATP mode is limited by both the command line and the "mmu-type" > + * property in the device tree, since some platforms may hang if an unsupported > + * SATP mode is attempted. > */ > static __init void set_satp_mode(uintptr_t dtb_pa) > { > u64 identity_satp, hw_satp; > uintptr_t set_satp_mode_pmd = ((unsigned long)set_satp_mode) & PMD_MASK; > - u64 satp_mode_cmdline = __pi_set_satp_mode_from_cmdline(dtb_pa); > + u64 satp_mode_limit = min_not_zero(__pi_set_satp_mode_from_cmdline(dtb_pa), > + __pi_set_satp_mode_from_fdt(dtb_pa)); > > kernel_map.page_offset = PAGE_OFFSET_L5; > > - if (satp_mode_cmdline == SATP_MODE_48) { > + if (satp_mode_limit == SATP_MODE_48) { > disable_pgtable_l5(); > - } else if (satp_mode_cmdline == SATP_MODE_39) { > + } else if (satp_mode_limit == SATP_MODE_39) { > disable_pgtable_l5(); > disable_pgtable_l4(); > return; _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode 2025-07-21 16:53 ` [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode Junhui Liu 2025-07-22 4:36 ` Nutty Liu @ 2025-07-25 14:04 ` Alexandre Ghiti 2025-07-25 16:29 ` Junhui Liu 1 sibling, 1 reply; 9+ messages in thread From: Alexandre Ghiti @ 2025-07-25 14:04 UTC (permalink / raw) To: Junhui Liu, Paul Walmsley, Palmer Dabbelt, Albert Ou Cc: linux-riscv, linux-kernel On 7/21/25 18:53, Junhui Liu wrote: > Some RISC-V implementations may hang when attempting to write an > unsupported SATP mode, even though the latest RISC-V specification > states such writes should have no effect. To avoid this issue, the > logic for selecting SATP mode has been refined: > > The kernel now determines the SATP mode limit by taking the minimum of > the value specified by the kernel command line (noXlvl) and the > "mmu-type" property in the device tree (FDT). If only one is specified, > use that. > - If the resulting limit is sv48 or higher, the kernel will probe SATP > modes from this limit downward until a supported mode is found. > - If the limit is sv39, the kernel will directly use sv39 without > probing. > > This ensures SATP mode selection is safe and compatible with both > hardware and user configuration, minimizing the risk of hangs. > > Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> > --- > arch/riscv/kernel/pi/fdt_early.c | 40 ++++++++++++++++++++++++++++++++++++++++ > arch/riscv/kernel/pi/pi.h | 1 + > arch/riscv/mm/init.c | 11 ++++++++--- > 3 files changed, 49 insertions(+), 3 deletions(-) > > diff --git a/arch/riscv/kernel/pi/fdt_early.c b/arch/riscv/kernel/pi/fdt_early.c > index 9bdee2fafe47e4a889132ebe2d0d360717c464e9..a12ff8090f190331f555d9e22ce4d1b3e940bceb 100644 > --- a/arch/riscv/kernel/pi/fdt_early.c > +++ b/arch/riscv/kernel/pi/fdt_early.c > @@ -3,6 +3,7 @@ > #include <linux/init.h> > #include <linux/libfdt.h> > #include <linux/ctype.h> > +#include <asm/csr.h> > > #include "pi.h" > > @@ -183,3 +184,42 @@ bool fdt_early_match_extension_isa(const void *fdt, const char *ext_name) > > return ret; > } > + > +/** > + * set_satp_mode_from_fdt - determine SATP mode based on the MMU type in fdt > + * > + * @dtb_pa: physical address of the device tree blob > + * > + * Returns the SATP mode corresponding to the MMU type of the first enabled CPU, > + * 0 otherwise > + */ > +u64 set_satp_mode_from_fdt(uintptr_t dtb_pa) > +{ > + const void *fdt = (const void *)dtb_pa; > + const char *mmu_type; > + int node, parent; > + > + parent = fdt_path_offset(fdt, "/cpus"); > + if (parent < 0) > + return 0; > + > + fdt_for_each_subnode(node, fdt, parent) { > + if (!fdt_node_name_eq(fdt, node, "cpu")) > + continue; > + > + if (!fdt_device_is_available(fdt, node)) > + continue; > + > + mmu_type = fdt_getprop(fdt, node, "mmu-type", NULL); > + if (!mmu_type) > + break; > + > + if (!strcmp(mmu_type, "riscv,sv39")) > + return SATP_MODE_39; > + else if (!strcmp(mmu_type, "riscv,sv48")) > + return SATP_MODE_48; > + break; > + } > + > + return 0; > +} > diff --git a/arch/riscv/kernel/pi/pi.h b/arch/riscv/kernel/pi/pi.h > index 21141d84fea603fdfc439e12a8c3216f1527c65f..3fee2cfddf7cfb8179af6f2d9b69a0d5e412fad7 100644 > --- a/arch/riscv/kernel/pi/pi.h > +++ b/arch/riscv/kernel/pi/pi.h > @@ -14,6 +14,7 @@ u64 get_kaslr_seed(uintptr_t dtb_pa); > u64 get_kaslr_seed_zkr(const uintptr_t dtb_pa); > bool set_nokaslr_from_cmdline(uintptr_t dtb_pa); > u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa); > +u64 set_satp_mode_from_fdt(uintptr_t dtb_pa); > > bool fdt_early_match_extension_isa(const void *fdt, const char *ext_name); > > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c > index d03e02a92379f2338a4f4df0ab797a7859b83dfc..0f30fa875abf92a201579ac6469958b0d95b5a58 100644 > --- a/arch/riscv/mm/init.c > +++ b/arch/riscv/mm/init.c > @@ -816,6 +816,7 @@ static __meminit pgprot_t pgprot_from_va(uintptr_t va) > > #if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL) > u64 __pi_set_satp_mode_from_cmdline(uintptr_t dtb_pa); > +u64 __pi_set_satp_mode_from_fdt(uintptr_t dtb_pa); > > static void __init disable_pgtable_l5(void) > { > @@ -855,18 +856,22 @@ static void __init set_mmap_rnd_bits_max(void) > * underlying hardware: establish 1:1 mapping in 4-level page table mode > * then read SATP to see if the configuration was taken into account > * meaning sv48 is supported. > + * The maximum SATP mode is limited by both the command line and the "mmu-type" > + * property in the device tree, since some platforms may hang if an unsupported > + * SATP mode is attempted. > */ > static __init void set_satp_mode(uintptr_t dtb_pa) > { > u64 identity_satp, hw_satp; > uintptr_t set_satp_mode_pmd = ((unsigned long)set_satp_mode) & PMD_MASK; > - u64 satp_mode_cmdline = __pi_set_satp_mode_from_cmdline(dtb_pa); > + u64 satp_mode_limit = min_not_zero(__pi_set_satp_mode_from_cmdline(dtb_pa), > + __pi_set_satp_mode_from_fdt(dtb_pa)); > > kernel_map.page_offset = PAGE_OFFSET_L5; > > - if (satp_mode_cmdline == SATP_MODE_48) { > + if (satp_mode_limit == SATP_MODE_48) { > disable_pgtable_l5(); > - } else if (satp_mode_cmdline == SATP_MODE_39) { > + } else if (satp_mode_limit == SATP_MODE_39) { > disable_pgtable_l5(); > disable_pgtable_l4(); > return; > I guess it's more convenient to use the 'mmu-type' property on this core rather than using no4lvl right? Anyway, what you implemented matches the description of the 'mmu-type' binding, so: Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com> I'll take that for 6.17. Thanks, Alex _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode 2025-07-25 14:04 ` Alexandre Ghiti @ 2025-07-25 16:29 ` Junhui Liu 0 siblings, 0 replies; 9+ messages in thread From: Junhui Liu @ 2025-07-25 16:29 UTC (permalink / raw) To: Alexandre Ghiti, Paul Walmsley, Palmer Dabbelt, Albert Ou Cc: linux-riscv, linux-kernel On 25/07/2025 16:04, Alexandre Ghiti wrote: > On 7/21/25 18:53, Junhui Liu wrote: >> Some RISC-V implementations may hang when attempting to write an >> unsupported SATP mode, even though the latest RISC-V specification >> states such writes should have no effect. To avoid this issue, the >> logic for selecting SATP mode has been refined: >> >> The kernel now determines the SATP mode limit by taking the minimum of >> the value specified by the kernel command line (noXlvl) and the >> "mmu-type" property in the device tree (FDT). If only one is specified, >> use that. >> - If the resulting limit is sv48 or higher, the kernel will probe SATP >> modes from this limit downward until a supported mode is found. >> - If the limit is sv39, the kernel will directly use sv39 without >> probing. >> >> This ensures SATP mode selection is safe and compatible with both >> hardware and user configuration, minimizing the risk of hangs. >> >> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> >> --- >> arch/riscv/kernel/pi/fdt_early.c | 40 ++++++++++++++++++++++++++++++++++++++++ >> arch/riscv/kernel/pi/pi.h | 1 + >> arch/riscv/mm/init.c | 11 ++++++++--- >> 3 files changed, 49 insertions(+), 3 deletions(-) >> [...] > > I guess it's more convenient to use the 'mmu-type' property on this core > rather than using no4lvl right? Yes, It's hard to ensure that all the users are aware of the need to use the 'no4lvl', and the cmdline args can easily be overridden by the bootloader or users if a `bootargs = "no4lvl"` is defined in the device tree. Therefore, relying on the 'mmu-type' property is more robust and user-friendly. > > Anyway, what you implemented matches the description of the 'mmu-type' > binding, so: > > Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com> > > I'll take that for 6.17. Thanks! > > Thanks, > > Alex -- Best regards, Junhui Liu _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit 2025-07-21 16:53 [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit Junhui Liu 2025-07-21 16:53 ` [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options Junhui Liu 2025-07-21 16:53 ` [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode Junhui Liu @ 2025-08-06 17:15 ` patchwork-bot+linux-riscv 2 siblings, 0 replies; 9+ messages in thread From: patchwork-bot+linux-riscv @ 2025-08-06 17:15 UTC (permalink / raw) To: Junhui Liu; +Cc: linux-riscv, paul.walmsley, palmer, aou, alex, linux-kernel Hello: This series was applied to riscv/linux.git (for-next) by Alexandre Ghiti <alexghiti@rivosinc.com>: On Tue, 22 Jul 2025 00:53:09 +0800 you wrote: > This patch series improves RISC-V kernel compatibility and robustness by > refining how the SATP mode is determined during early boot. Some RISC-V > implementations, such as the Anlogic DR1V90 FPSoC with a UX900 RISC-V > core designed by Nuclei, which I am currently attempting to run the > mainline kernel on [1], may hang when attempting to write an unsupported > SATP mode. > > [...] Here is the summary with links: - [1/2] riscv: mm: Return intended SATP mode for noXlvl options https://git.kernel.org/riscv/c/75ede0a8e07b - [2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode https://git.kernel.org/riscv/c/a870d4f78f11 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-08-06 17:19 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-07-21 16:53 [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit Junhui Liu 2025-07-21 16:53 ` [PATCH 1/2] riscv: mm: Return intended SATP mode for noXlvl options Junhui Liu 2025-07-22 4:33 ` Nutty Liu 2025-07-25 14:02 ` Alexandre Ghiti 2025-07-21 16:53 ` [PATCH 2/2] riscv: mm: Use mmu-type from FDT to limit SATP mode Junhui Liu 2025-07-22 4:36 ` Nutty Liu 2025-07-25 14:04 ` Alexandre Ghiti 2025-07-25 16:29 ` Junhui Liu 2025-08-06 17:15 ` [PATCH 0/2] riscv: mm: Use mmu-type from FDT as SATP mode limit patchwork-bot+linux-riscv
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).