From: Keir Fraser Date: Wed, 17 Oct 2007 10:12:32 +0000 (+0100) Subject: x86: Remove invlpg_works_ok and invlpg only single-page regions. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14847^2~32 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=9255c493f176349d34576261c220b4fb7faafb4e;p=xen.git 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 --- diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c index 4ed95ea6a7..13fec06717 100644 --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -373,11 +373,6 @@ static void __init init_amd(struct cpuinfo_x86 *c) if ((smp_processor_id() == 1) && c1_ramping_may_cause_clock_drift(c)) disable_c1_ramping(); - /* Support INVLPG of superpages? */ - __set_bit(2, &c->invlpg_works_ok); - if ( cpu_has(c, X86_FEATURE_PAGE1GB) ) - __set_bit(3, &c->invlpg_works_ok); - start_svm(c); } diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index a578a7b108..c333ac36f2 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -314,7 +314,6 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) c->x86_vendor_id[0] = '\0'; /* Unset */ c->x86_model_id[0] = '\0'; /* Unset */ c->x86_max_cores = 1; - c->invlpg_works_ok = 1; /* no superpage INVLPG by default */ c->x86_clflush_size = 0; memset(&c->x86_capability, 0, sizeof c->x86_capability); diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c index c3daf2987d..5fcad2403a 100644 --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c @@ -123,18 +123,6 @@ static void __devinit init_intel(struct cpuinfo_x86 *c) if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) clear_bit(X86_FEATURE_SEP, c->x86_capability); - /* Supports INVLPG of superpages? */ - __set_bit(2, &c->invlpg_works_ok); - if (/* PentiumPro erratum 30 */ - (c->x86 == 6 && c->x86_model == 1 && c->x86_mask < 9) || - /* Dual-Core Intel Xeon 3000/5100 series erratum 89/90 */ - /* Quad-Core Intel Xeon 3200/5300 series erratum 89/88 */ - /* Intel Core2 erratum 89 */ - (c->x86 == 6 && c->x86_model == 15 ) || - /* Dual-Core Intel Xeon LV/ULV erratum 75 */ - (c->x86 == 6 && c->x86_model == 14 )) - __clear_bit(2, &c->invlpg_works_ok); - /* Names for the Pentium II/Celeron processors detectable only by also checking the cache size. Dixon is NOT a Celeron. */ 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" ); } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index c0e62fdada..c2247918d9 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -114,7 +114,7 @@ struct tss_struct init_tss[NR_CPUS]; char __attribute__ ((__section__(".bss.stack_aligned"))) cpu0_stack[STACK_SIZE]; -struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, 1, -1 }; +struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1 }; #if CONFIG_PAGING_LEVELS > 2 unsigned long mmu_cr4_features = X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE; diff --git a/xen/include/asm-x86/flushtlb.h b/xen/include/asm-x86/flushtlb.h index 7e67ec23b4..7dff2e74bd 100644 --- a/xen/include/asm-x86/flushtlb.h +++ b/xen/include/asm-x86/flushtlb.h @@ -78,6 +78,7 @@ void write_cr3(unsigned long cr3); * 1 -> 4kB area containing specified virtual address * 2 -> 4MB/2MB area containing specified virtual address * 3 -> 1GB area containing specified virtual address (x86/64 only) + * NB. Multi-page areas do not need to have been mapped with a superpage. */ #define FLUSH_LEVEL_MASK 0x0f #define FLUSH_LEVEL(x) (x) diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 8ed9ecb67c..0af78e21c1 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -164,7 +164,6 @@ struct cpuinfo_x86 { __u8 x86_vendor; /* CPU vendor */ __u8 x86_model; __u8 x86_mask; - __u8 invlpg_works_ok; int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ unsigned int x86_capability[NCAPINTS]; char x86_vendor_id[16];