aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/flushtlb.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-10-17 11:12:32 +0100
committerKeir Fraser <keir@xensource.com>2007-10-17 11:12:32 +0100
commit9255c493f176349d34576261c220b4fb7faafb4e (patch)
treee0dad031d700585fbfd94d527ef91f2bbe82a1ca /xen/arch/x86/flushtlb.c
parent3e43914aa8f2b569d99da99ce412e3a47e1906c7 (diff)
downloadxen-9255c493f176349d34576261c220b4fb7faafb4e.tar.gz
xen-9255c493f176349d34576261c220b4fb7faafb4e.tar.bz2
xen-9255c493f176349d34576261c220b4fb7faafb4e.zip
x86: Remove invlpg_works_ok and invlpg only single-page regions.
The flush_area_local() interface was unclear about whether a multi-page region (2M/4M/1G) had to be mapped by a superpage, and indeed some callers (map_pages_to_xen()) already would specify FLUSH_LEVEL(2) for a region actually mapped by 4kB PTEs. The safest fix is to relax the interface and do a full TLB flush in these cases. My suspicion is that these cases are rare enough that the cost of INVLPG versus full flush will be unimportant. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/arch/x86/flushtlb.c')
-rw-r--r--xen/arch/x86/flushtlb.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/xen/arch/x86/flushtlb.c b/xen/arch/x86/flushtlb.c
index 69aa7fa21d..808b848de5 100644
--- a/xen/arch/x86/flushtlb.c
+++ b/xen/arch/x86/flushtlb.c
@@ -108,8 +108,14 @@ void flush_area_local(const void *va, unsigned int flags)
if ( flags & (FLUSH_TLB|FLUSH_TLB_GLOBAL) )
{
- if ( (level != 0) && test_bit(level, &c->invlpg_works_ok) )
+ if ( level == 1 )
{
+ /*
+ * We don't INVLPG multi-page regions because the 2M/4M/1G
+ * region may not have been mapped with a superpage. Also there
+ * are various errata surrounding INVLPG usage on superpages, and
+ * a full flush is in any case not *that* expensive.
+ */
asm volatile ( "invlpg %0"
: : "m" (*(const char *)(va)) : "memory" );
}