@@ -37,10 +37,8 @@ static inline void __tlb_remove_table(void *_table)
#include <asm-generic/tlb.h>
static inline void
-__pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long addr)
+__pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *ptdesc, unsigned long addr)
{
- struct ptdesc *ptdesc = page_ptdesc(pte);
-
pagetable_pte_dtor(ptdesc);
#ifndef CONFIG_ARM_LPAE
@@ -77,11 +77,9 @@ static inline void tlb_flush(struct mmu_gather *tlb)
last_level, tlb_level);
}
-static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *ptdesc,
unsigned long addr)
{
- struct ptdesc *ptdesc = page_ptdesc(pte);
-
pagetable_pte_dtor(ptdesc);
tlb_remove_ptdesc(tlb, ptdesc);
}
@@ -63,8 +63,8 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
#define __pte_free_tlb(tlb, pte, address) \
do { \
- pagetable_pte_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc(tlb, page_ptdesc(pte)); \
+ pagetable_pte_dtor(pte); \
+ tlb_remove_page_ptdesc(tlb, pte); \
} while (0)
extern void pagetable_init(void);
@@ -89,8 +89,8 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
#define __pte_free_tlb(tlb, pte, addr) \
do { \
- pagetable_pte_dtor((page_ptdesc(pte))); \
- tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \
+ pagetable_pte_dtor((pte)); \
+ tlb_remove_page_ptdesc((tlb), (pte)); \
} while (0)
#endif
@@ -46,8 +46,8 @@ extern pgd_t *pgd_alloc(struct mm_struct *mm);
#define __pte_free_tlb(tlb, pte, address) \
do { \
- pagetable_pte_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), page_ptdesc(pte)); \
+ pagetable_pte_dtor(pte); \
+ tlb_remove_page_ptdesc((tlb), pte); \
} while (0)
#ifndef __PAGETABLE_PMD_FOLDED
@@ -44,10 +44,10 @@ static inline void pte_free(struct mm_struct *mm, struct ptdesc *ptdesc)
free_pointer_table(ptdesc_page(ptdesc), TABLE_PTE);
}
-static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pgtable,
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *ptdesc,
unsigned long address)
{
- free_pointer_table(pgtable, TABLE_PTE);
+ free_pointer_table(ptdesc_page(ptdesc), TABLE_PTE);
}
@@ -68,8 +68,8 @@ extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
#define __pte_free_tlb(tlb, pte, addr) \
do { \
- pagetable_pte_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \
+ pagetable_pte_dtor(pte); \
+ tlb_remove_page_ptdesc((tlb), (pte)); \
} while (0)
#endif
@@ -64,7 +64,7 @@ static inline void __tlb_remove_table(void *_table)
pgtable_free(table, shift);
}
-static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *table,
unsigned long address)
{
pgtable_free_tlb(tlb, table, 0);
@@ -167,7 +167,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
*pmd = __pmd(__pgtable_ptr_val(pte_page) | PMD_VAL_BITS);
}
-static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *table,
unsigned long address)
{
pgtable_free_tlb(tlb, table, PTE_INDEX);
@@ -183,13 +183,11 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
#endif /* __PAGETABLE_PMD_FOLDED */
-static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *pte,
unsigned long addr)
{
- struct ptdesc *ptdesc = page_ptdesc(pte);
-
- pagetable_pte_dtor(ptdesc);
- riscv_tlb_remove_ptdesc(tlb, ptdesc);
+ pagetable_pte_dtor(pte);
+ riscv_tlb_remove_ptdesc(tlb, pte);
}
#endif /* CONFIG_MMU */
@@ -53,9 +53,9 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
extern struct ptdesc *pte_alloc_one(struct mm_struct *);
-extern void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte);
+extern void ___pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *pte);
-static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *pte,
unsigned long address)
{
___pte_free_tlb(tlb, pte);
@@ -50,10 +50,10 @@ static int __init setup_userpte(char *arg)
}
early_param("userpte", setup_userpte);
-void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
+void ___pte_free_tlb(struct mmu_gather *tlb, struct ptdesc *pte)
{
- pagetable_pte_dtor(page_ptdesc(pte));
- paravirt_release_pte(page_to_pfn(pte));
+ pagetable_pte_dtor(pte);
+ paravirt_release_pte(ptdesc_pfn(pte));
paravirt_tlb_remove_table(tlb, pte);
}
@@ -2859,6 +2859,20 @@ static inline bool pagetable_is_reserved(struct ptdesc *pt)
return folio_test_reserved(ptdesc_folio(pt));
}
+/**
+ * ptdesc_pfn - Return the Page Frame Number of a ptdesc.
+ * @ptdesc: The ptdesc.
+ *
+ * A ptdesc may contain multiple pages. The pages have consecutive
+ * Page Frame Numbers.
+ *
+ * Return: The Page Frame Number of the first page in the ptdesc.
+ */
+static inline unsigned long ptdesc_pfn(struct ptdesc *ptdesc)
+{
+ return page_to_pfn(ptdesc_page(ptdesc));
+}
+
/**
* pagetable_alloc - Allocate pagetables
* @gfp: GFP flags
@@ -189,7 +189,8 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member)
static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
unsigned long addr)
{
- pgtable_t token = pmd_pgtable(*pmd);
+ struct ptdesc *token = (struct ptdesc *)pmd_pgtable(*pmd);
+
pmd_clear(pmd);
pte_free_tlb(tlb, token, addr);
mm_dec_nr_ptes(tlb->mm);