The invlpg instruction causes strange signal 11 problem on some
PentiumPro box.  This problem seems to hapen when (1) mother board is
very old and (2) BIOS update is not available and (3) cpuid < 0x619.

Following patch automatically disables invlpg when PentiumPro with
cpuid < 0x619 is found.

Please comment to this patch.

---------- BEGIN ----------
*** sys/i386/isa/initcpu.c.ORIG Sat Jul  1 01:03:40 2000
--- sys/i386/isa/initcpu.c      Sat Jul  1 01:06:28 2000
***************
*** 46,51 ****
--- 46,55 ----
  void  enable_K6_2_wt_alloc(void);
  #endif
  
+ #ifdef I686_CPU
+ extern        int invlpgbug;
+ #endif
+ 
  #ifdef I486_CPU
  static void init_5x86(void);
  static void init_bluelightning(void);
***************
*** 449,454 ****
--- 453,462 ----
        apicbase = rdmsr(0x1b);
        apicbase &= ~0x800LL;
        wrmsr(0x1b, apicbase);
+ #endif
+ #ifndef CPU_DONT_DISABLE_INVLPG
+       if (cpu_id < 0x619)
+               invlpgbug = 1;
  #endif
  }
  
*** sys/i386/isa/pmap.c.ORIG    Sat Jul  1 01:06:46 2000
--- sys/i386/isa/pmap.c Sat Jul  1 01:13:37 2000
***************
*** 171,176 ****
--- 171,181 ----
  static struct pv_entry *pvinit;
  
  /*
+  * When invlpgbug = 1, we don't use invlpg instruction.
+  */
+ int   invlpgbug;
+ 
+ /*
   * All those kernel PT submaps that BSD is so fond of
   */
  pt_entry_t *CMAP1 = 0;
***************
*** 358,364 ****
  
        pgeflag = 0;
  #if !defined(SMP)
!       if (cpu_feature & CPUID_PGE) {
                pgeflag = PG_G;
        }
  #endif
--- 363,369 ----
  
        pgeflag = 0;
  #if !defined(SMP)
!       if (cpu_feature & CPUID_PGE && !invlpg) {
                pgeflag = PG_G;
        }
  #endif
***************
*** 581,587 ****
        } else
  #endif
        {
!               invlpg(va);
        }
  }
  
--- 586,595 ----
        } else
  #endif
        {
!               if (invlpgbug)
!                       invltlb();
!               else
!                       invlpg(va);
        }
  }
  
***************
*** 884,890 ****
                 */
                *(ptek + i) = VM_PAGE_TO_PHYS(m) | PG_RW | PG_V | pgeflag;
                if (oldpte) {
!                       if ((oldpte & PG_G) || (cpu_class > CPUCLASS_386)) {
                                invlpg((vm_offset_t) up + i * PAGE_SIZE);
                        } else {
                                updateneeded = 1;
--- 892,899 ----
                 */
                *(ptek + i) = VM_PAGE_TO_PHYS(m) | PG_RW | PG_V | pgeflag;
                if (oldpte) {
!                       if (((oldpte & PG_G) || (cpu_class > CPUCLASS_386)) &&
!                           !invlpgbug) {
                                invlpg((vm_offset_t) up + i * PAGE_SIZE);
                        } else {
                                updateneeded = 1;
***************
*** 925,931 ****
  
                oldpte = *(ptek + i);
                *(ptek + i) = 0;
!               if ((oldpte & PG_G) || (cpu_class > CPUCLASS_386))
                        invlpg((vm_offset_t) p->p_addr + i * PAGE_SIZE);
                vm_page_unwire(m, 0);
                vm_page_free(m);
--- 934,940 ----
  
                oldpte = *(ptek + i);
                *(ptek + i) = 0;
!               if (((oldpte & PG_G) || (cpu_class > CPUCLASS_386)) && !invlpgbug)
                        invlpg((vm_offset_t) p->p_addr + i * PAGE_SIZE);
                vm_page_unwire(m, 0);
                vm_page_free(m);
***************
*** 933,938 ****
--- 942,950 ----
  #if defined(I386_CPU)
        if (cpu_class <= CPUCLASS_386)
                invltlb();
+ #else
+       if (invlpgbug)
+               invltlb();
  #endif
  }
  
***************
*** 2785,2792 ****
        } else
  #endif
        {
!               invlpg((u_int)CADDR1);
!               invlpg((u_int)CADDR2);
        }
  
        bcopy(CADDR1, CADDR2, PAGE_SIZE);
--- 2797,2808 ----
        } else
  #endif
        {
!               if (invlpgbug)
!                       invltlb();
!               else {
!                       invlpg((u_int)CADDR1);
!                       invlpg((u_int)CADDR2);
!               }
        }
  
        bcopy(CADDR1, CADDR2, PAGE_SIZE);
---------- END ----------

-----------------------------------------------+--------------------------+
KATO Takenori <[EMAIL PROTECTED]>  |        FreeBSD           |
Dept. Earth Planet. Sci, Nagoya Univ.          |    The power to serve!   |
Nagoya, 464-8602, Japan                        |  http://www.FreeBSD.org/ |
++++ FreeBSD(98) 4.0R-Rev. 01 available!       |http://www.jp.FreeBSD.org/|
++++ FreeBSD(98) 3.4R-Rev. 01 available!       +==========================+



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to