linux-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [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

* [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 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 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 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

* 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).