[PATCH 7.1 301/438] riscv/mm: use physical alignment for vmemmap_start_pfn

Greg Kroah-Hartman <[email protected]>
Newsgroups dev.linux.lists.patches,org.kernel.vger.stable
Message-ID <[email protected]>
7.1-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jiakai Xu <[email protected]>

commit 45ebe4540817cb540a59e4dc04014ac5dddc9990 upstream.

RISC-V computes vmemmap_start_pfn by rounding phys_ram_base down to
VMEMMAP_ADDR_ALIGN.  That alignment must therefore be expressed in the
physical-address domain.

Commit 476849b0fba4 ("riscv/mm: align vmemmap to maximal folio size")
attempted to account for the maximal folio alignment by feeding
MAX_FOLIO_VMEMMAP_ALIGN directly into VMEMMAP_ADDR_ALIGN.  However,
MAX_FOLIO_VMEMMAP_ALIGN is measured in bytes of struct page storage,
whereas VMEMMAP_ADDR_ALIGN is used to align a physical address.

The mask-based compound_info encoding requires pfn_to_page(0) to be
naturally aligned to MAX_FOLIO_VMEMMAP_ALIGN.  Commit 9f94db4c7eaa
("mm/sparse: check memmap alignment for compound_info_has_mask()") added a
check for that requirement and exposed the unit mismatch on systems such
as QEMU virt, where the DRAM base is not aligned to MAX_FOLIO_NR_PAGES *
PAGE_SIZE.

Here is the log:
[    0.000000][    C0] ------------[ cut here ]------------
[    0.000000][    C0] WARNING: mm/sparse.c:365 at sparse_init+0x58a/0x6fe, CPU#0: swapper/0
[    0.000000][    C0] Modules linked in:
[    0.000000][    C0] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 7.2.0-rc3-g1d8304bdd65f #2 PREEMPT
[    0.000000][    C0] Hardware name: riscv-virtio,qemu (DT)
[    0.000000][    C0] epc : sparse_init+0x58a/0x6fe
[    0.000000][    C0]  ra : sparse_init+0x58a/0x6fe
[    0.000000][    C0] epc : ffffffff86851c88 ra : ffffffff86851c88 sp : ffffffff88807a30
[    0.000000][    C0]  gp : ffffffff8a3bf240 tp : ffffffff88842080 t0 : ff600000ffab6000
[    0.000000][    C0]  t1 : 000000017fab6000 t2 : 65203a6573726363 s0 : ffffffff88807bc0
[    0.000000][    C0]  s1 : 000000000e000000 a0 : 0000000000000007 a1 : 0000000000000000
[    0.000000][    C0]  a2 : 0000000000000002 a3 : ffffffff86851c88 a4 : 0000000000000000
[    0.000000][    C0]  a5 : ffffffff88843080 a6 : 0000000000000003 a7 : 0000000000000000
[    0.000000][    C0]  s2 : ff60000000000000 s3 : 0040000000000000 s4 : 0004000000000000
[    0.000000][    C0]  s5 : ffffffff8a4d92e0 s6 : ff600000ffab55e0 s7 : ffffffff88384d00
[    0.000000][    C0]  s8 : 0000000000000003 s9 : ffffffff88384cc1 s10: ffffffff88384cc0
[    0.000000][    C0]  s11: ffffffff8a4daae0 t3 : ffffffff915e8b20 t4 : ffffffff915e8b20
[    0.000000][    C0]  t5 : ffffffff915e8b20 t6 : ffffffff915e8bc8 ssp : 0000000000000000
[    0.000000][    C0] status: 0000000200000100 badaddr: ffffffff86851c88 cause: 0000000000000003
[    0.000000][    C0] [<ffffffff86851c88>] sparse_init+0x58a/0x6fe
[    0.000000][    C0] [<ffffffff8683d396>] mm_core_init_early+0x116/0x1e30
[    0.000000][    C0] [<ffffffff86801edc>] start_kernel+0xd2/0x848

Convert MAX_FOLIO_VMEMMAP_ALIGN to the equivalent physical alignment
before using it in VMEMMAP_ADDR_ALIGN.  This keeps the existing
round_down() logic while making the resulting vmemmap base satisfy the
mask-alignment requirement.

Link: https://lore.kernel.org/[email protected]
Fixes: 476849b0fba4 ("riscv/mm: align vmemmap to maximal folio size")
Signed-off-by: Jiakai Xu <[email protected]>
Reviewed-by: Kiryl Shutsemau (Meta) <[email protected]>
Cc: Albert Ou <[email protected]>
Cc: Alexandre Ghiti <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Guo Ren <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Muchun Song <[email protected]>
Cc: Nam Cao <[email protected]>
Cc: Palmer Dabbelt <[email protected]>
Cc: Vishal Moola (Oracle) <[email protected]>
Assisted-by: YuanSheng:DeepSeek-V4-Flash
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 arch/riscv/mm/init.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -61,7 +61,8 @@ EXPORT_SYMBOL(phys_ram_base);
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 #define VMEMMAP_ADDR_ALIGN	max(1ULL << SECTION_SIZE_BITS, \
-				    MAX_FOLIO_VMEMMAP_ALIGN)
+				    PFN_PHYS(MAX_FOLIO_VMEMMAP_ALIGN / \
+					     sizeof(struct page)))
 
 unsigned long vmemmap_start_pfn __ro_after_init;
 EXPORT_SYMBOL(vmemmap_start_pfn);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.