[PATCH 6.1.y] riscv: Don't use PGD entries for the linear mapping

From: Ben Zong-You Xie

Date: Thu Aug 20 2026 - 02:35:13 EST


From: Alexandre Ghiti <alexghiti@xxxxxxxxxxxx>

commit 629db01c64ff6cea08fc61b52426362689ef8618 upstream.

Propagating changes at this level is cumbersome as we need to go through
all the page tables when that happens (either when changing the
permissions or when splitting the mapping).

Note that this prevents the use of 4MB mapping for sv32 and 1GB mapping for
sv39 in the linear mapping.

Signed-off-by: Alexandre Ghiti <alexghiti@xxxxxxxxxxxx>
Link: https://lore.kernel.org/r/20231108075930.7157-2-alexghiti@xxxxxxxxxxxx
Signed-off-by: Palmer Dabbelt <palmer@xxxxxxxxxxxx>
[ Ben: Only backport the RV32 guard. 6.1.y can build the RV32 linear
mapping from PGD entries, and there is no splitting in __set_memory().
So a one-page permission change mutates 1024 pages.]
Signed-off-by: Ben Zong-You Xie <ben717@xxxxxxxxxxxxx>
---
arch/riscv/mm/init.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 72b3462babbf..7e6ea7f0cb68 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -666,8 +666,13 @@ void __init create_pgd_mapping(pgd_t *pgdp,

static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size)
{
- /* Upgrade to PMD_SIZE mappings whenever possible */
- if ((base & (PMD_SIZE - 1)) || (size & (PMD_SIZE - 1)))
+ /*
+ * Upgrade to PMD_SIZE mappings whenever possible. Not on 32-bit,
+ * where PMD_SIZE == PGDIR_SIZE: such a mapping is a PGD leaf entry
+ * that __set_memory() is unable to split.
+ */
+ if (!IS_ENABLED(CONFIG_64BIT) ||
+ (base & (PMD_SIZE - 1)) || (size & (PMD_SIZE - 1)))
return PAGE_SIZE;

return PMD_SIZE;
--
2.34.1