aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Ghiti <[email protected]>2023-09-28 17:18:46 +0200
committerAndrew Morton <[email protected]>2023-10-06 14:11:38 -0700
commit1de195dd0e05d9cba43dec16f83d4ee32af94dd2 (patch)
tree9629c3f36a61936cd36b4425f6cd90e8c0f6f405
parent117b1bb0cbc7f5feab4fd251737869958987808c (diff)
riscv: fix set_huge_pte_at() for NAPOT mappings when a swap entry is set
We used to determine the number of page table entries to set for a NAPOT hugepage by using the pte value which actually fails when the pte to set is a swap entry. So take advantage of a recent fix for arm64 reported in [1] which introduces the size of the mapping as an argument of set_huge_pte_at(): we can then use this size to compute the number of page table entries to set for a NAPOT region. Link: https://lkml.kernel.org/r/[email protected] Fixes: 82a1a1f3bfb6 ("riscv: mm: support Svnapot in hugetlb page") Signed-off-by: Alexandre Ghiti <[email protected]> Reported-by: Ryan Roberts <[email protected]> Closes: https://lore.kernel.org/linux-arm-kernel/[email protected]/ [1] Reviewed-by: Andrew Jones <[email protected]> Cc: Albert Ou <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Paul Walmsley <[email protected]> Cc: Qinglin Pan <[email protected]> Cc: Conor Dooley <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
-rw-r--r--arch/riscv/mm/hugetlbpage.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
index e4a2ace92dbe..b52f0210481f 100644
--- a/arch/riscv/mm/hugetlbpage.c
+++ b/arch/riscv/mm/hugetlbpage.c
@@ -183,15 +183,22 @@ void set_huge_pte_at(struct mm_struct *mm,
pte_t pte,
unsigned long sz)
{
+ unsigned long hugepage_shift;
int i, pte_num;
- if (!pte_napot(pte)) {
- set_pte_at(mm, addr, ptep, pte);
- return;
- }
+ if (sz >= PGDIR_SIZE)
+ hugepage_shift = PGDIR_SHIFT;
+ else if (sz >= P4D_SIZE)
+ hugepage_shift = P4D_SHIFT;
+ else if (sz >= PUD_SIZE)
+ hugepage_shift = PUD_SHIFT;
+ else if (sz >= PMD_SIZE)
+ hugepage_shift = PMD_SHIFT;
+ else
+ hugepage_shift = PAGE_SHIFT;
- pte_num = napot_pte_num(napot_cont_order(pte));
- for (i = 0; i < pte_num; i++, ptep++, addr += PAGE_SIZE)
+ pte_num = sz >> hugepage_shift;
+ for (i = 0; i < pte_num; i++, ptep++, addr += (1 << hugepage_shift))
set_pte_at(mm, addr, ptep, pte);
}