[PATCH 2/2] riscv: mm: check the valid bit in kernel_page_present()

Mike Rapoport (Microsoft) rppt at kernel.org
Thu Nov 12 05:42:19 PST 2026


set_direct_map_invalid_noflush() clears _PAGE_PRESENT, but the kernel
mappings keep _PAGE_PROT_NONE set: it used to be _PAGE_READ and now it is
the same bit as _PAGE_GLOBAL. pte_present() and pmd_present() still
return true for the invalidated entry. kernel_page_present() then reports
that an unmapped page is mapped, and hibernation copies it without
remapping it first.

Test _PAGE_PRESENT directly for PMD and PTE leaves.

Fixes: 32a0de886eb3 ("arch, mm: make kernel_page_present() always available")
Signed-off-by: Mike Rapoport (Microsoft) <rppt at kernel.org>
---
 arch/riscv/mm/pageattr.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index b138113755359..62fbcf7cf36b6 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -453,8 +453,9 @@ bool kernel_page_present(struct page *page)
 	if (!pmd_present(pmdp_get(pmd)))
 		return false;
 	if (pmd_leaf(pmdp_get(pmd)))
-		return true;
+		return pmd_val(pmdp_get(pmd)) & _PAGE_PRESENT;
 
+	/* pte_present() is true for PAGE_KERNEL with _PAGE_PRESENT cleared */
 	pte = pte_offset_kernel(pmd, addr);
-	return pte_present(ptep_get(pte));
+	return pte_val(ptep_get(pte)) & _PAGE_PRESENT;
 }

-- 
2.53.0




More information about the linux-riscv mailing list