diff options
author | Richard Braun <rbraun@sceen.net> | 2013-06-28 20:44:33 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2013-06-28 20:44:33 +0200 |
commit | 722366c46be7a75dd13429cb7efb1144ac913f76 (patch) | |
tree | 975cde395e125aa30e3dd9ae19ab9661112cb31a | |
parent | 757bcadf8732ca7c1a0acaac9115dc788c4f6d28 (diff) |
x86/cpu: new cpu_tlb_flush_all function
This function completely flushes the TLB, including global pages.
-rw-r--r-- | arch/x86/machine/cpu.h | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/arch/x86/machine/cpu.h b/arch/x86/machine/cpu.h index 9749353c..d655496e 100644 --- a/arch/x86/machine/cpu.h +++ b/arch/x86/machine/cpu.h @@ -284,30 +284,6 @@ CPU_DECL_GETSET_CR(cr3) CPU_DECL_GETSET_CR(cr4) /* - * Flush the whole TLB. - * - * Implies a compiler barrier. - */ -static __always_inline void -cpu_tlb_flush(void) -{ - cpu_set_cr3(cpu_get_cr3()); -} - -/* - * Flush a single page table entry in the TLB. In some cases, the entire TLB - * can be flushed by this instruction. The va parameter is a virtual - * address in the page described by the PTE to flush. - * - * Implies a compiler barrier. - */ -static __always_inline void -cpu_tlb_flush_va(unsigned long va) -{ - asm volatile("invlpg (%0)" : : "r" (va) : "memory"); -} - -/* * Return the content of the EFLAGS register. * * Implies a compiler barrier. @@ -532,6 +508,54 @@ cpu_set_msr(uint32_t msr, uint32_t low, uint32_t high) } /* + * Flush non-global TLB entries. + * + * Implies a compiler barrier. + */ +static __always_inline void +cpu_tlb_flush(void) +{ + cpu_set_cr3(cpu_get_cr3()); +} + +/* + * Flush all TLB entries, including global ones. + * + * Implies a compiler barrier. + */ +static __always_inline void +cpu_tlb_flush_all(void) +{ + if (!cpu_has_global_pages()) + cpu_tlb_flush(); + else { + unsigned long cr4; + + cr4 = cpu_get_cr4(); + + if (!(cr4 & CPU_CR4_PGE)) + cpu_tlb_flush(); + else { + cr4 &= ~CPU_CR4_PGE; + cpu_set_cr4(cr4); + cr4 |= CPU_CR4_PGE; + cpu_set_cr4(cr4); + } + } +} + +/* + * Flush a single page table entry in the TLB. + * + * Implies a compiler barrier. + */ +static __always_inline void +cpu_tlb_flush_va(unsigned long va) +{ + asm volatile("invlpg (%0)" : : "r" (va) : "memory"); +} + +/* * XXX For now, directly use the PIT. */ static __always_inline void |