|
@@ -68,6 +68,32 @@ static int find_num_contig(struct mm_struct *mm, unsigned long addr,
|
|
|
return CONT_PTES;
|
|
|
}
|
|
|
|
|
|
+static inline int num_contig_ptes(unsigned long size, size_t *pgsize)
|
|
|
+{
|
|
|
+ int contig_ptes = 0;
|
|
|
+
|
|
|
+ *pgsize = size;
|
|
|
+
|
|
|
+ switch (size) {
|
|
|
+#ifdef CONFIG_ARM64_4K_PAGES
|
|
|
+ case PUD_SIZE:
|
|
|
+#endif
|
|
|
+ case PMD_SIZE:
|
|
|
+ contig_ptes = 1;
|
|
|
+ break;
|
|
|
+ case CONT_PMD_SIZE:
|
|
|
+ *pgsize = PMD_SIZE;
|
|
|
+ contig_ptes = CONT_PMDS;
|
|
|
+ break;
|
|
|
+ case CONT_PTE_SIZE:
|
|
|
+ *pgsize = PAGE_SIZE;
|
|
|
+ contig_ptes = CONT_PTES;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return contig_ptes;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Changing some bits of contiguous entries requires us to follow a
|
|
|
* Break-Before-Make approach, breaking the whole contiguous set
|
|
@@ -262,6 +288,18 @@ pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
|
|
|
return entry;
|
|
|
}
|
|
|
|
|
|
+void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
|
|
|
+ pte_t *ptep, unsigned long sz)
|
|
|
+{
|
|
|
+ int i, ncontig;
|
|
|
+ size_t pgsize;
|
|
|
+
|
|
|
+ ncontig = num_contig_ptes(sz, &pgsize);
|
|
|
+
|
|
|
+ for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
|
|
|
+ pte_clear(mm, addr, ptep);
|
|
|
+}
|
|
|
+
|
|
|
pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
|
|
|
unsigned long addr, pte_t *ptep)
|
|
|
{
|