@@ -190,7 +190,9 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_isset((pte), L_PTE_PRESENT))
#define pte_valid(pte) (pte_isset((pte), L_PTE_VALID))
-#define pte_accessible(mm, pte) (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte))
+#define pte_accessible(vma, pte) \
+ (pte_tlb_flush_pending(vma, pte) ? \
+ pte_present(*pte) : pte_valid(*pte))
#define pte_write(pte) (pte_isclear((pte), L_PTE_RDONLY))
#define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY))
#define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG))
@@ -126,8 +126,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
* flag, since ptep_clear_flush_young() elides a DSB when invalidating the
* TLB.
*/
-#define pte_accessible(mm, pte) \
- (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte))
+#define pte_accessible(vma, pte) \
+ (pte_tlb_flush_pending(vma, pte) ? pte_present(*pte) : pte_valid(*pte))
/*
* p??_access_permitted() is true for valid user mappings (subject to the
@@ -673,9 +673,9 @@ static inline unsigned long pte_present(pte_t pte)
}
#define pte_accessible pte_accessible
-static inline unsigned long pte_accessible(struct mm_struct *mm, pte_t a)
+static inline unsigned long pte_accessible(struct vm_area_struct *vma, pte_t *a)
{
- return pte_val(a) & _PAGE_VALID;
+ return pte_val(*a) & _PAGE_VALID;
}
static inline unsigned long pte_special(pte_t pte)
@@ -906,8 +906,11 @@ static void maybe_tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
*
* SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
* and SUN4V pte layout, so this inline test is fine.
+ *
+ * The vma is not propagated to this point, but it is not used by
+ * sparc's pte_accessible(). We therefore provide NULL.
*/
- if (likely(mm != &init_mm) && pte_accessible(mm, orig))
+ if (likely(mm != &init_mm) && pte_accessible(NULL, ptep))
tlb_batch_add(mm, vaddr, ptep, orig, fullmm, hugepage_shift);
}
@@ -404,7 +404,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *
mm = vma->vm_mm;
/* Don't insert a non-valid PTE into the TSB, we'll deadlock. */
- if (!pte_accessible(mm, pte))
+ if (!pte_accessible(vma, ptep))
return;
spin_lock_irqsave(&mm->context.lock, flags);
@@ -775,13 +775,12 @@ static inline int pte_devmap(pte_t a)
#endif
#define pte_accessible pte_accessible
-static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
+static inline bool pte_accessible(struct vm_area_struct *vma, pte_t *a)
{
- if (pte_flags(a) & _PAGE_PRESENT)
+ if (pte_flags(*a) & _PAGE_PRESENT)
return true;
- if ((pte_flags(a) & _PAGE_PROTNONE) &&
- mm_tlb_flush_pending(mm))
+ if ((pte_flags(*a) & _PAGE_PROTNONE) && pte_tlb_flush_pending(vma, a))
return true;
return false;
@@ -682,6 +682,16 @@ static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
return atomic_read(&mm->tlb_flush_pending);
}
+static inline bool pte_tlb_flush_pending(struct vm_area_struct *vma, pte_t *pte)
+{
+ return mm_tlb_flush_pending(vma->vm_mm);
+}
+
+static inline bool pmd_tlb_flush_pending(struct vm_area_struct *vma, pmd_t *pmd)
+{
+ return mm_tlb_flush_pending(vma->vm_mm);
+}
+
static inline bool mm_tlb_flush_nested(struct mm_struct *mm)
{
/*
@@ -725,7 +725,7 @@ static inline void arch_swap_restore(swp_entry_t entry, struct page *page)
#endif
#ifndef pte_accessible
-# define pte_accessible(mm, pte) ((void)(pte), 1)
+# define pte_accessible(vma, pte) ((void)(pte), 1)
#endif
#ifndef flush_tlb_fix_spurious_fault
@@ -1514,7 +1514,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
* We are not sure a pending tlb flush here is for a huge page
* mapping or not. Hence use the tlb range variant
*/
- if (mm_tlb_flush_pending(vma->vm_mm)) {
+ if (pmd_tlb_flush_pending(vma, vmf->pmd)) {
flush_tlb_range(vma, haddr, haddr + HPAGE_PMD_SIZE);
/*
* change_huge_pmd() released the pmd lock before
@@ -1060,7 +1060,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte) ||
(pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte)) ||
- mm_tlb_flush_pending(mm)) {
+ pte_tlb_flush_pending(vma, pvmw.pte)) {
pte_t entry;
swapped = PageSwapCache(page);
@@ -93,7 +93,7 @@ pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long address,
struct mm_struct *mm = (vma)->vm_mm;
pte_t pte;
pte = ptep_get_and_clear(mm, address, ptep);
- if (pte_accessible(mm, pte))
+ if (pte_accessible(vma, ptep))
flush_tlb_page(vma, address);
return pte;
}