Commit 195568a1 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Ley Foon Tan
Browse files

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: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarLey Foon Tan <ley.foon.tan@intel.com>
parent ef5cbcb6
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -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 */
+1 −1
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ vmalloc_fault:
		if (!pte_present(*pte_k))
			goto no_context;

		flush_tlb_one(address);
		flush_tlb_kernel_page(address);
		return;
	}
}
+9 −9
Original line number Diff line number Diff line
@@ -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;