summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--i386/i386/proc_reg.h11
-rw-r--r--i386/intel/pmap.c9
3 files changed, 25 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index d0125e2..edb4a89 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-02-26 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * i386/i386/prog_reg.h (invlpg_linear): Rename macro into...
+ (invlpg_linear_range): ... this.
+ (invlpg_linear): New macro.
+ * i386/intel/pmap.c (INVALIDATE_TLB): Call invlpg_linear instead
+ of flush_tlb when e - S is compile-time known to be PAGE_SIZE,
+ instead of run-time known to be less than 32 * PAGE_SIZE.
+
2009-01-05 Samuel Thibault <samuel.thibault@ens-lyon.org>
* i386/i386/gdt.h (LINEAR_DS): New macro.
diff --git a/i386/i386/proc_reg.h b/i386/i386/proc_reg.h
index 11a21cf..d9f32bc 100644
--- a/i386/i386/proc_reg.h
+++ b/i386/i386/proc_reg.h
@@ -142,7 +142,16 @@ set_eflags(unsigned eflags)
asm volatile("invlpg (%0)" : : "r" (addr)); \
})
-#define invlpg_linear(start, end) \
+#define invlpg_linear(start) \
+ ({ \
+ asm volatile( \
+ "movw %w1,%%es\n" \
+ "\tinvlpg %%es:(%0)\n" \
+ "\tmovw %w2,%%es" \
+ :: "r" (start), "q" (LINEAR_DS), "q" (KERNEL_DS)); \
+ })
+
+#define invlpg_linear_range(start, end) \
({ \
register unsigned long var = trunc_page(start); \
asm volatile( \
diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c
index d46f645..d57df92 100644
--- a/i386/intel/pmap.c
+++ b/i386/intel/pmap.c
@@ -332,11 +332,14 @@ lock_data_t pmap_system_lock;
#define MAX_TBIS_SIZE 32 /* > this -> TBIA */ /* XXX */
#if 0
+/* It is hard to know when a TLB flush becomes less expensive than a bunch of
+ * invlpgs. But it surely is more expensive than just one invlpg. */
#define INVALIDATE_TLB(s, e) { \
- if (((e) - (s)) > 32 * PAGE_SIZE) \
- flush_tlb(); \
+ if (__builtin_constant_p((e) - (s))
+ && (e) - (s) == PAGE_SIZE)
+ invlpg_linear(s); \
else \
- invlpg_linear(s, e); \
+ flush_tlb(); \
}
#else
#define INVALIDATE_TLB(s, e) flush_tlb()