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:
parent
ef5cbcb6bf
commit
195568a10a
|
@ -26,21 +26,26 @@ struct mm_struct;
|
||||||
*
|
*
|
||||||
* - flush_tlb_all() flushes all processes TLB entries
|
* - flush_tlb_all() flushes all processes TLB entries
|
||||||
* - flush_tlb_mm(mm) flushes the specified mm context 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_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_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_all(void);
|
||||||
extern void flush_tlb_mm(struct mm_struct *mm);
|
extern void flush_tlb_mm(struct mm_struct *mm);
|
||||||
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
||||||
unsigned long end);
|
unsigned long end);
|
||||||
extern void flush_tlb_kernel_range(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,
|
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 */
|
#endif /* _ASM_NIOS2_TLBFLUSH_H */
|
||||||
|
|
|
@ -271,7 +271,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
|
||||||
if (!pte_present(*pte_k))
|
if (!pte_present(*pte_k))
|
||||||
goto no_context;
|
goto no_context;
|
||||||
|
|
||||||
flush_tlb_one(address);
|
flush_tlb_kernel_page(address);
|
||||||
return;
|
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
|
* This one is only used for pages with the global bit set so we don't care
|
||||||
* much about the ASID.
|
* much about the ASID.
|
||||||
*/
|
*/
|
||||||
void flush_tlb_one(unsigned long addr)
|
static void flush_tlb_one(unsigned long addr)
|
||||||
{
|
{
|
||||||
unsigned int way;
|
unsigned int way;
|
||||||
unsigned long org_misc, pid_misc;
|
unsigned long org_misc, pid_misc;
|
||||||
|
@ -154,6 +146,14 @@ void flush_tlb_one(unsigned long addr)
|
||||||
WRCTL(CTL_TLBMISC, org_misc);
|
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)
|
void dump_tlb_line(unsigned long line)
|
||||||
{
|
{
|
||||||
unsigned int way;
|
unsigned int way;
|
||||||
|
|
Loading…
Reference in New Issue