ia64/xen-unstable

changeset 16144:76bf1fcaf01d

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>
author Keir Fraser <keir@xensource.com>
date Wed Oct 17 11:12:32 2007 +0100 (2007-10-17)
parents 86bd91e90eec
children d994e6d3136d
files xen/arch/x86/cpu/amd.c xen/arch/x86/cpu/common.c xen/arch/x86/cpu/intel.c xen/arch/x86/flushtlb.c xen/arch/x86/setup.c xen/include/asm-x86/flushtlb.h xen/include/asm-x86/processor.h
line diff
     1.1 --- a/xen/arch/x86/cpu/amd.c	Wed Oct 17 10:02:49 2007 +0100
     1.2 +++ b/xen/arch/x86/cpu/amd.c	Wed Oct 17 11:12:32 2007 +0100
     1.3 @@ -373,11 +373,6 @@ static void __init init_amd(struct cpuin
     1.4  	if ((smp_processor_id() == 1) && c1_ramping_may_cause_clock_drift(c))
     1.5  		disable_c1_ramping();
     1.6  
     1.7 -	/* Support INVLPG of superpages? */
     1.8 -	__set_bit(2, &c->invlpg_works_ok);
     1.9 -	if ( cpu_has(c, X86_FEATURE_PAGE1GB) )
    1.10 -		__set_bit(3, &c->invlpg_works_ok);
    1.11 -
    1.12  	start_svm(c);
    1.13  }
    1.14  
     2.1 --- a/xen/arch/x86/cpu/common.c	Wed Oct 17 10:02:49 2007 +0100
     2.2 +++ b/xen/arch/x86/cpu/common.c	Wed Oct 17 11:12:32 2007 +0100
     2.3 @@ -314,7 +314,6 @@ void __devinit identify_cpu(struct cpuin
     2.4  	c->x86_vendor_id[0] = '\0'; /* Unset */
     2.5  	c->x86_model_id[0] = '\0';  /* Unset */
     2.6  	c->x86_max_cores = 1;
     2.7 -	c->invlpg_works_ok = 1; /* no superpage INVLPG by default */
     2.8  	c->x86_clflush_size = 0;
     2.9  	memset(&c->x86_capability, 0, sizeof c->x86_capability);
    2.10  
     3.1 --- a/xen/arch/x86/cpu/intel.c	Wed Oct 17 10:02:49 2007 +0100
     3.2 +++ b/xen/arch/x86/cpu/intel.c	Wed Oct 17 11:12:32 2007 +0100
     3.3 @@ -123,18 +123,6 @@ static void __devinit init_intel(struct 
     3.4  	if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
     3.5  		clear_bit(X86_FEATURE_SEP, c->x86_capability);
     3.6  
     3.7 -	/* Supports INVLPG of superpages? */
     3.8 -	__set_bit(2, &c->invlpg_works_ok);
     3.9 -	if (/* PentiumPro erratum 30 */
    3.10 -	    (c->x86 == 6 && c->x86_model == 1 && c->x86_mask < 9) ||
    3.11 -	    /* Dual-Core Intel Xeon 3000/5100 series erratum 89/90 */
    3.12 -	    /* Quad-Core Intel Xeon 3200/5300 series erratum 89/88 */
    3.13 -	    /* Intel Core2 erratum 89 */
    3.14 -	    (c->x86 == 6 && c->x86_model == 15 ) ||
    3.15 -	    /* Dual-Core Intel Xeon LV/ULV erratum 75 */
    3.16 -	    (c->x86 == 6 && c->x86_model == 14 ))
    3.17 -		__clear_bit(2, &c->invlpg_works_ok);
    3.18 -
    3.19  	/* Names for the Pentium II/Celeron processors 
    3.20  	   detectable only by also checking the cache size.
    3.21  	   Dixon is NOT a Celeron. */
     4.1 --- a/xen/arch/x86/flushtlb.c	Wed Oct 17 10:02:49 2007 +0100
     4.2 +++ b/xen/arch/x86/flushtlb.c	Wed Oct 17 11:12:32 2007 +0100
     4.3 @@ -108,8 +108,14 @@ void flush_area_local(const void *va, un
     4.4  
     4.5      if ( flags & (FLUSH_TLB|FLUSH_TLB_GLOBAL) )
     4.6      {
     4.7 -        if ( (level != 0) && test_bit(level, &c->invlpg_works_ok) )
     4.8 +        if ( level == 1 )
     4.9          {
    4.10 +            /*
    4.11 +             * We don't INVLPG multi-page regions because the 2M/4M/1G
    4.12 +             * region may not have been mapped with a superpage. Also there
    4.13 +             * are various errata surrounding INVLPG usage on superpages, and
    4.14 +             * a full flush is in any case not *that* expensive.
    4.15 +             */
    4.16              asm volatile ( "invlpg %0"
    4.17                             : : "m" (*(const char *)(va)) : "memory" );
    4.18          }
     5.1 --- a/xen/arch/x86/setup.c	Wed Oct 17 10:02:49 2007 +0100
     5.2 +++ b/xen/arch/x86/setup.c	Wed Oct 17 11:12:32 2007 +0100
     5.3 @@ -114,7 +114,7 @@ struct tss_struct init_tss[NR_CPUS];
     5.4  
     5.5  char __attribute__ ((__section__(".bss.stack_aligned"))) cpu0_stack[STACK_SIZE];
     5.6  
     5.7 -struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, 1, -1 };
     5.8 +struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1 };
     5.9  
    5.10  #if CONFIG_PAGING_LEVELS > 2
    5.11  unsigned long mmu_cr4_features = X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE;
     6.1 --- a/xen/include/asm-x86/flushtlb.h	Wed Oct 17 10:02:49 2007 +0100
     6.2 +++ b/xen/include/asm-x86/flushtlb.h	Wed Oct 17 11:12:32 2007 +0100
     6.3 @@ -78,6 +78,7 @@ void write_cr3(unsigned long cr3);
     6.4    *  1 -> 4kB area containing specified virtual address
     6.5    *  2 -> 4MB/2MB area containing specified virtual address
     6.6    *  3 -> 1GB area containing specified virtual address (x86/64 only)
     6.7 +  * NB. Multi-page areas do not need to have been mapped with a superpage.
     6.8    */
     6.9  #define FLUSH_LEVEL_MASK 0x0f
    6.10  #define FLUSH_LEVEL(x)   (x)
     7.1 --- a/xen/include/asm-x86/processor.h	Wed Oct 17 10:02:49 2007 +0100
     7.2 +++ b/xen/include/asm-x86/processor.h	Wed Oct 17 11:12:32 2007 +0100
     7.3 @@ -164,7 +164,6 @@ struct cpuinfo_x86 {
     7.4      __u8 x86_vendor;     /* CPU vendor */
     7.5      __u8 x86_model;
     7.6      __u8 x86_mask;
     7.7 -    __u8 invlpg_works_ok;
     7.8      int  cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
     7.9      unsigned int x86_capability[NCAPINTS];
    7.10      char x86_vendor_id[16];