diff mbox series

[RFC,v2,11/21] riscv: mm: Reimplement mk_huge_pte function

Message ID 20241205103729.14798-12-luxu.kernel@bytedance.com (mailing list archive)
State New
Headers show
Series riscv: Introduce 64K base page | expand

Checks

Context Check Description
conchuod/vmtest-for-next-PR fail PR summary
conchuod/patch-11-test-1 success .github/scripts/patches/tests/build_rv32_defconfig.sh took 209.18s
conchuod/patch-11-test-2 success .github/scripts/patches/tests/build_rv64_clang_allmodconfig.sh took 1413.24s
conchuod/patch-11-test-3 success .github/scripts/patches/tests/build_rv64_gcc_allmodconfig.sh took 1620.25s
conchuod/patch-11-test-4 success .github/scripts/patches/tests/build_rv64_nommu_k210_defconfig.sh took 78.84s
conchuod/patch-11-test-5 success .github/scripts/patches/tests/build_rv64_nommu_virt_defconfig.sh took 80.93s
conchuod/patch-11-test-6 warning .github/scripts/patches/tests/checkpatch.sh took 1.55s
conchuod/patch-11-test-7 success .github/scripts/patches/tests/dtb_warn_rv64.sh took 48.60s
conchuod/patch-11-test-8 success .github/scripts/patches/tests/header_inline.sh took 0.01s
conchuod/patch-11-test-9 success .github/scripts/patches/tests/kdoc.sh took 0.67s
conchuod/patch-11-test-10 success .github/scripts/patches/tests/module_param.sh took 0.04s
conchuod/patch-11-test-11 success .github/scripts/patches/tests/verify_fixes.sh took 0.00s
conchuod/patch-11-test-12 success .github/scripts/patches/tests/verify_signedoff.sh took 0.04s
conchuod/vmtest-fixes-PR fail merge-conflict

Commit Message

Xu Lu Dec. 5, 2024, 10:37 a.m. UTC
Huge pte can be pud, pmd, or svnapot pte. Huge ptes from different page
table levels have different pte constructors. This commit reimplements
mk_huge_pte function. We take vma struct as argument to check the target
huge pte level and applying corresponding constructor.

Signed-off-by: Xu Lu <luxu.kernel@bytedance.com>
---
 arch/riscv/include/asm/hugetlb.h |  5 +++++
 arch/riscv/mm/hugetlbpage.c      | 23 ++++++++++++++++++++++-
 arch/s390/include/asm/hugetlb.h  |  2 +-
 include/asm-generic/hugetlb.h    |  5 ++++-
 mm/debug_vm_pgtable.c            |  2 +-
 mm/hugetlb.c                     |  4 ++--
 6 files changed, 35 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
index faf3624d8057..eafd00f4b74f 100644
--- a/arch/riscv/include/asm/hugetlb.h
+++ b/arch/riscv/include/asm/hugetlb.h
@@ -51,6 +51,11 @@  pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
 
 #endif /*CONFIG_RISCV_ISA_SVNAPOT*/
 
+#ifdef CONFIG_RISCV_USE_SW_PAGE
+#define __HAVE_ARCH_MK_HUGE_PTE
+pte_t mk_huge_pte(struct vm_area_struct *vma, struct page *page, pgprot_t pgprot);
+#endif
+
 #include <asm-generic/hugetlb.h>
 
 #endif /* _ASM_RISCV_HUGETLB_H */
diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
index 42314f093922..8896c28ec881 100644
--- a/arch/riscv/mm/hugetlbpage.c
+++ b/arch/riscv/mm/hugetlbpage.c
@@ -2,6 +2,27 @@ 
 #include <linux/hugetlb.h>
 #include <linux/err.h>
 
+#ifdef CONFIG_RISCV_USE_SW_PAGE
+pte_t mk_huge_pte(struct vm_area_struct *vma, struct page *page, pgprot_t pgprot)
+{
+	pte_t pte;
+	unsigned int shift = huge_page_shift(hstate_vma(vma));
+
+	if (shift == PGDIR_SHIFT)
+		pte = pgd_pte(pfn_pgd(page_to_pfn(page), pgprot));
+	else if (shift == P4D_SHIFT)
+		pte = p4d_pte(pfn_p4d(page_to_pfn(page), pgprot));
+	else if (shift == PUD_SHIFT)
+		pte = pud_pte(pfn_pud(page_to_pfn(page), pgprot));
+	else if (shift == PMD_SHIFT)
+		pte = pmd_pte(pfn_pmd(page_to_pfn(page), pgprot));
+	else
+		pte = pfn_pte(page_to_pfn(page), pgprot);
+
+	return pte;
+}
+#endif /* CONFIG_RISCV_USE_SW_PAGE */
+
 #ifdef CONFIG_RISCV_ISA_SVNAPOT
 pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
@@ -74,7 +95,7 @@  pte_t *huge_pte_alloc(struct mm_struct *mm,
 
 out:
 	if (pte) {
-		pte_t pteval = ptep_get_lockless(pte);
+		pte_t pteval = ptep_get(pte);
 
 		WARN_ON_ONCE(pte_present(pteval) && !pte_huge(pteval));
 	}
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index cf1b5d6fb1a6..cea9118d4bba 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -79,7 +79,7 @@  static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 	__set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
 }
 
-static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
+static inline pte_t mk_huge_pte(struct vm_area_struct *vma, struct page *page, pgprot_t pgprot)
 {
 	return mk_pte(page, pgprot);
 }
diff --git a/include/asm-generic/hugetlb.h b/include/asm-generic/hugetlb.h
index 594d5905f615..90765bc03bba 100644
--- a/include/asm-generic/hugetlb.h
+++ b/include/asm-generic/hugetlb.h
@@ -5,10 +5,13 @@ 
 #include <linux/swap.h>
 #include <linux/swapops.h>
 
-static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
+#ifndef __HAVE_ARCH_MK_HUGE_PTE
+static inline pte_t mk_huge_pte(struct vm_area_struct *vma, struct page *page,
+				pgprot_t pgprot)
 {
 	return mk_pte(page, pgprot);
 }
+#endif
 
 static inline unsigned long huge_pte_write(pte_t pte)
 {
diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
index 1cec548cc6c7..24839883d513 100644
--- a/mm/debug_vm_pgtable.c
+++ b/mm/debug_vm_pgtable.c
@@ -919,7 +919,7 @@  static void __init hugetlb_basic_tests(struct pgtable_debug_args *args)
 	 * as it was previously derived from a real kernel symbol.
 	 */
 	page = pfn_to_page(args->fixed_pmd_pfn);
-	pte = mk_huge_pte(page, args->page_prot);
+	pte = mk_huge_pte(args->vma, page, args->page_prot);
 
 	WARN_ON(!huge_pte_dirty(huge_pte_mkdirty(pte)));
 	WARN_ON(!huge_pte_write(huge_pte_mkwrite(huge_pte_wrprotect(pte))));
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 190fa05635f4..2b33eb46408f 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5140,10 +5140,10 @@  static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page,
 	unsigned int shift = huge_page_shift(hstate_vma(vma));
 
 	if (writable) {
-		entry = huge_pte_mkwrite(huge_pte_mkdirty(mk_huge_pte(page,
+		entry = huge_pte_mkwrite(huge_pte_mkdirty(mk_huge_pte(vma, page,
 					 vma->vm_page_prot)));
 	} else {
-		entry = huge_pte_wrprotect(mk_huge_pte(page,
+		entry = huge_pte_wrprotect(mk_huge_pte(vma, page,
 					   vma->vm_page_prot));
 	}
 	entry = pte_mkyoung(entry);