		Cache and TLB Flushing
		     Under Linux


	    David S. Miller <davem@redhat.com>

This document describes the cache/tlb flushing interfaces called
by the Linux VM subsystem.  It first enumerates over each interface,
describes it's intended purpose, and what side effect is expected
after the interface is invoked.  Finally, a section describing
implementation strategies for kernel porting folks is included.  The
idea behind this final section is to list some of the common cache/tlb
characteristics out there and show one way of going about supporting
them correctly.

The side effects described below are stated for a uniprocessor
implementation, and what is to happen on that single processor.
The SMP cases are a simple extension, in that you just extend the
definition such that the side effect for a particular interface occurs
on all processors in the system.  Don't let this scare you into
thinking SMP cache/tlb flushing must be so inefficient, it is in fact
this area where many optimizations are possible.

First, the TLB flushing interfaces, since they are the simplest.  The
"TLB" is abstracted under Linux as something the cpu uses to cache
virtual-->physical address translations obtained from the software
page tables.  Meaning that if the software page tables change, it is
possible for stale translations to exist in this "TLB" cache.
Therefore when software page table changes occur, the kernel will
invoke one of the following flush methods _after_ the page table
changes occur:

1) void flush_tlb_all(void)

	The most severe flush of all.  After this interface runs,
	any previous page table modification whatsoever will be
	visible to the cpu.

	This is usually invoked when the kernel page tables are
	changed, since such translations are "global" in nature.

2) void flush_tlb_mm(struct mm_struct *mm)

	This interface flushes an entire user address space from
	the TLB.  After running, this interface must make sure that
	any previous page table modifications for the address space
	'mm' will be visible to the cpu.  That is, after running,
	there will be no entries in the TLB for 'mm'.

	This interface is used to handle whole address space
	page table operations such as what happens during
	fork, exit, and exec.

3) void flush_tlb_range(struct mm_struct *mm,
			unsigned long start, unsigned long end)

	Here we are flushing a specific range of (user) virtual
	address translations from the TLB.  After running, this
	interface must make sure that any previous page table
	modifications for the address space 'mm' in the range 'start'
	to 'end' will be visible to the cpu.  That is, after running,
	there will be no entries in the TLB for 'mm' for virtual
	addresses in the range 'start' to 'end'.

	Primarily, this is used for munmap() type operations.

	The interface is provided in hopes that the port can find
	a suitably efficient method for removing multiple page
	sized translations from the TLB, instead of having the kernel
	call flush_tlb_page (see below) for each entry which may be
	modified.

4) void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)

	This time we need to remove the PAGE_SIZE sized translation
	from the TLB.  The 'vma' is the backing structure used by
	Linux to keep track of mmap'd regions for a process, the
	address space is available via vma->vm_mm.  Also, one may
	test (vma->vm_flags & VM_EXEC) to see if this region is
	executable (and thus could be in the 'instruction TLB' in
	split-tlb type setups).

	After running, this interface must make sure that any previous
	page table modification for address space 'vma->vm_mm' for
	user virtual address 'page' will be visible to the cpu.  That
	is, after running, there will be no entries in the TLB for
	'vma->vm_mm' for virtual address 'page'.

	This is used primarily during fault processing.

