aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86_64/tlbflush.h
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-09-26 04:52:29 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:29 -0400
commitb1c78c0fcc29097567e1afc39701012e6d89adb7 (patch)
tree9b9a2a302740c7a68003ade0536ab244f20cb08c /include/asm-x86_64/tlbflush.h
parent3f14c746a61ec932c204aca820c02c293118c5df (diff)
[PATCH] Clean up and minor fixes to TLB flush
- Convert CR* accesses to dedicated inline functions and rewrite the rest as C inlines - Don't do a double flush for global flushes (pointed out by Zach Amsden) This was a bug workaround for old CPUs that don't do 64bit and is obsolete. - Add a proper memory clobber to invlpg - Remove an unused extern Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'include/asm-x86_64/tlbflush.h')
-rw-r--r--include/asm-x86_64/tlbflush.h70
1 files changed, 35 insertions, 35 deletions
diff --git a/include/asm-x86_64/tlbflush.h b/include/asm-x86_64/tlbflush.h
index d16d5b60f419..983bd296c81a 100644
--- a/include/asm-x86_64/tlbflush.h
+++ b/include/asm-x86_64/tlbflush.h
@@ -4,44 +4,44 @@
4#include <linux/mm.h> 4#include <linux/mm.h>
5#include <asm/processor.h> 5#include <asm/processor.h>
6 6
7#define __flush_tlb() \ 7static inline unsigned long get_cr3(void)
8 do { \ 8{
9 unsigned long tmpreg; \ 9 unsigned long cr3;
10 \ 10 asm volatile("mov %%cr3,%0" : "=r" (cr3));
11 __asm__ __volatile__( \ 11 return cr3;
12 "movq %%cr3, %0; # flush TLB \n" \ 12}
13 "movq %0, %%cr3; \n" \
14 : "=r" (tmpreg) \
15 :: "memory"); \
16 } while (0)
17 13
18/* 14static inline void set_cr3(unsigned long cr3)
19 * Global pages have to be flushed a bit differently. Not a real 15{
20 * performance problem because this does not happen often. 16 asm volatile("mov %0,%%cr3" :: "r" (cr3) : "memory");
21 */ 17}
22#define __flush_tlb_global() \ 18
23 do { \ 19static inline void __flush_tlb(void)
24 unsigned long tmpreg, cr4, cr4_orig; \ 20{
25 \ 21 set_cr3(get_cr3());
26 __asm__ __volatile__( \ 22}
27 "movq %%cr4, %2; # turn off PGE \n" \ 23
28 "movq %2, %1; \n" \ 24static inline unsigned long get_cr4(void)
29 "andq %3, %1; \n" \ 25{
30 "movq %1, %%cr4; \n" \ 26 unsigned long cr4;
31 "movq %%cr3, %0; # flush TLB \n" \ 27 asm volatile("mov %%cr4,%0" : "=r" (cr4));
32 "movq %0, %%cr3; \n" \ 28 return cr4;
33 "movq %2, %%cr4; # turn PGE back on \n" \ 29}
34 : "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig) \ 30
35 : "i" (~X86_CR4_PGE) \ 31static inline void set_cr4(unsigned long cr4)
36 : "memory"); \ 32{
37 } while (0) 33 asm volatile("mov %0,%%cr4" :: "r" (cr4) : "memory");
38 34}
39extern unsigned long pgkern_mask; 35
40 36static inline void __flush_tlb_all(void)
41#define __flush_tlb_all() __flush_tlb_global() 37{
38 unsigned long cr4 = get_cr4();
39 set_cr4(cr4 & ~X86_CR4_PGE); /* clear PGE */
40 set_cr4(cr4); /* write old PGE again and flush TLBs */
41}
42 42
43#define __flush_tlb_one(addr) \ 43#define __flush_tlb_one(addr) \
44 __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr)) 44 __asm__ __volatile__("invlpg (%0)" :: "r" (addr) : "memory")
45 45
46 46
47/* 47/*