diff options
author | Keir Fraser <keir@xensource.com> | 2007-10-17 11:12:32 +0100 |
---|---|---|
committer | Keir Fraser <keir@xensource.com> | 2007-10-17 11:12:32 +0100 |
commit | 9255c493f176349d34576261c220b4fb7faafb4e (patch) | |
tree | e0dad031d700585fbfd94d527ef91f2bbe82a1ca /xen/arch/x86/flushtlb.c | |
parent | 3e43914aa8f2b569d99da99ce412e3a47e1906c7 (diff) | |
download | xen-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.c | 8 |
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" ); } |