nios2: flush_tlb_page use PID based flush
flush_tlb_page is for flushing user pages, so it should not be using flush_tlb_one (which flushes all pages). This patch implements it with the flush_tlb_range, which is a user flush that does the right thing. flush_tlb_one is made static to mm/tlb.c because it's a bit confusing. It is used in do_page_fault to flush the kernel non-linear mappings, so that is replaced with flush_tlb_kernel_page. The end result is that functionality is identical. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
This commit is contained in:
Родитель
ef5cbcb6bf
Коммит
195568a10a
|
@ -26,21 +26,26 @@ struct mm_struct;
|
|||
*
|
||||
* - flush_tlb_all() flushes all processes TLB entries
|
||||
* - flush_tlb_mm(mm) flushes the specified mm context TLB entries
|
||||
* - flush_tlb_page(vma, vmaddr) flushes one page
|
||||
* - flush_tlb_range(vma, start, end) flushes a range of pages
|
||||
* - flush_tlb_page(vma, address) flushes a page
|
||||
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
|
||||
* - flush_tlb_kernel_page(address) flushes a kernel page
|
||||
*/
|
||||
extern void flush_tlb_all(void);
|
||||
extern void flush_tlb_mm(struct mm_struct *mm);
|
||||
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
||||
unsigned long end);
|
||||
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||
extern void flush_tlb_one(unsigned long vaddr);
|
||||
|
||||
static inline void flush_tlb_page(struct vm_area_struct *vma,
|
||||
unsigned long addr)
|
||||
unsigned long address)
|
||||
{
|
||||
flush_tlb_one(addr);
|
||||
flush_tlb_range(vma, address, address + PAGE_SIZE);
|
||||
}
|
||||
|
||||
static inline void flush_tlb_kernel_page(unsigned long address)
|
||||
{
|
||||
flush_tlb_kernel_range(address, address + PAGE_SIZE);
|
||||
}
|
||||
|
||||
#endif /* _ASM_NIOS2_TLBFLUSH_H */
|
||||
|
|
|
@ -271,7 +271,7 @@ vmalloc_fault:
|
|||
if (!pte_present(*pte_k))
|
||||
goto no_context;
|
||||
|
||||
flush_tlb_one(address);
|
||||
flush_tlb_kernel_page(address);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,19 +102,11 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
|||
}
|
||||
}
|
||||
|
||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
while (start < end) {
|
||||
flush_tlb_one(start);
|
||||
start += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This one is only used for pages with the global bit set so we don't care
|
||||
* much about the ASID.
|
||||
*/
|
||||
void flush_tlb_one(unsigned long addr)
|
||||
static void flush_tlb_one(unsigned long addr)
|
||||
{
|
||||
unsigned int way;
|
||||
unsigned long org_misc, pid_misc;
|
||||
|
@ -154,6 +146,14 @@ void flush_tlb_one(unsigned long addr)
|
|||
WRCTL(CTL_TLBMISC, org_misc);
|
||||
}
|
||||
|
||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
while (start < end) {
|
||||
flush_tlb_one(start);
|
||||
start += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void dump_tlb_line(unsigned long line)
|
||||
{
|
||||
unsigned int way;
|
||||
|
|
Загрузка…
Ссылка в новой задаче