|
@@ -112,6 +112,7 @@ struct mmu_gather {
|
|
* that that we can adjust the range after the flush
|
|
* that that we can adjust the range after the flush
|
|
*/
|
|
*/
|
|
unsigned long addr;
|
|
unsigned long addr;
|
|
|
|
+ int page_size;
|
|
};
|
|
};
|
|
|
|
|
|
#define HAVE_GENERIC_MMU_GATHER
|
|
#define HAVE_GENERIC_MMU_GATHER
|
|
@@ -120,7 +121,8 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long
|
|
void tlb_flush_mmu(struct mmu_gather *tlb);
|
|
void tlb_flush_mmu(struct mmu_gather *tlb);
|
|
void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
|
|
void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
|
|
unsigned long end);
|
|
unsigned long end);
|
|
-bool __tlb_remove_page(struct mmu_gather *tlb, struct page *page);
|
|
|
|
|
|
+extern bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page,
|
|
|
|
+ int page_size);
|
|
|
|
|
|
static inline void __tlb_adjust_range(struct mmu_gather *tlb,
|
|
static inline void __tlb_adjust_range(struct mmu_gather *tlb,
|
|
unsigned long address)
|
|
unsigned long address)
|
|
@@ -145,23 +147,36 @@ static inline void __tlb_reset_range(struct mmu_gather *tlb)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline void tlb_remove_page_size(struct mmu_gather *tlb,
|
|
|
|
+ struct page *page, int page_size)
|
|
|
|
+{
|
|
|
|
+ if (__tlb_remove_page_size(tlb, page, page_size)) {
|
|
|
|
+ tlb_flush_mmu(tlb);
|
|
|
|
+ tlb->page_size = page_size;
|
|
|
|
+ __tlb_adjust_range(tlb, tlb->addr);
|
|
|
|
+ __tlb_remove_page_size(tlb, page, page_size);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static bool __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
|
|
|
+{
|
|
|
|
+ return __tlb_remove_page_size(tlb, page, PAGE_SIZE);
|
|
|
|
+}
|
|
|
|
+
|
|
/* tlb_remove_page
|
|
/* tlb_remove_page
|
|
* Similar to __tlb_remove_page but will call tlb_flush_mmu() itself when
|
|
* Similar to __tlb_remove_page but will call tlb_flush_mmu() itself when
|
|
* required.
|
|
* required.
|
|
*/
|
|
*/
|
|
static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
|
static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
|
{
|
|
{
|
|
- if (__tlb_remove_page(tlb, page)) {
|
|
|
|
- tlb_flush_mmu(tlb);
|
|
|
|
- __tlb_adjust_range(tlb, tlb->addr);
|
|
|
|
- __tlb_remove_page(tlb, page);
|
|
|
|
- }
|
|
|
|
|
|
+ return tlb_remove_page_size(tlb, page, PAGE_SIZE);
|
|
}
|
|
}
|
|
|
|
|
|
static inline bool __tlb_remove_pte_page(struct mmu_gather *tlb, struct page *page)
|
|
static inline bool __tlb_remove_pte_page(struct mmu_gather *tlb, struct page *page)
|
|
{
|
|
{
|
|
/* active->nr should be zero when we call this */
|
|
/* active->nr should be zero when we call this */
|
|
VM_BUG_ON_PAGE(tlb->active->nr, page);
|
|
VM_BUG_ON_PAGE(tlb->active->nr, page);
|
|
|
|
+ tlb->page_size = PAGE_SIZE;
|
|
__tlb_adjust_range(tlb, tlb->addr);
|
|
__tlb_adjust_range(tlb, tlb->addr);
|
|
return __tlb_remove_page(tlb, page);
|
|
return __tlb_remove_page(tlb, page);
|
|
}
|
|
}
|