Often times I hear complaints like "my Mac hangs after upgrading to 
8.1" or "snapshot CD hangs on my brand new Mac".  I know some of 
these complaints started happening when we switched to new PAT 
layout.  It is so puzzling because it never happened on non-Apple 
hardware, AFAIK.  I really like to fix this problem but I cannot 
afford a Mac. :-P

If you are one of those lucky people, please test the attached patch 
and report your hardware model and any improvement or regression.

Also, I added a new tunable "vm.pmap.pat_works" so that you can turn 
it off from loader (i.e., "set vm.pmap.pat_works=0") and restore old 
behaviour without recompiling a new kernel.

Thanks in advance!

Jung-uk Kim
Index: sys/amd64/amd64/pmap.c
===================================================================
--- sys/amd64/amd64/pmap.c      (revision 215352)
+++ sys/amd64/amd64/pmap.c      (working copy)
@@ -180,10 +180,13 @@ static vm_paddr_t dmaplimit;
 vm_offset_t kernel_vm_end = VM_MIN_KERNEL_ADDRESS;
 pt_entry_t pg_nx;
 
-static int pat_works = 0;              /* Is page attribute table sane? */
-
 SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
 
+static int pat_works = 1;
+TUNABLE_INT("vm.pmap.pat_works", &pat_works);
+SYSCTL_INT(_vm_pmap, OID_AUTO, pat_works, CTLFLAG_RDTUN, &pat_works, 1,
+    "Is page attribute table fully functional?");
+
 static int pg_ps_enabled = 1;
 SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RDTUN, &pg_ps_enabled, 0,
     "Are large page mappings enabled?");
@@ -609,35 +612,15 @@ void
 pmap_init_pat(void)
 {
        uint64_t pat_msr;
-       char *sysenv;
-       static int pat_tested = 0;
 
        /* Bail if this CPU doesn't implement PAT. */
        if (!(cpu_feature & CPUID_PAT))
                panic("no PAT??");
 
-       /*
-        * Some Apple Macs based on nVidia chipsets cannot enter ACPI mode
-        * via SMI# when we use upper 4 PAT entries for unknown reason.
-        */
-       if (!pat_tested) {
-               pat_works = 1;
-               sysenv = getenv("smbios.system.product");
-               if (sysenv != NULL) {
-                       if (strncmp(sysenv, "MacBook5,1", 10) == 0 ||
-                           strncmp(sysenv, "MacBookPro5,5", 13) == 0 ||
-                           strncmp(sysenv, "Macmini3,1", 10) == 0 ||
-                           strncmp(sysenv, "iMac9,1", 7) == 0)
-                               pat_works = 0;
-                       freeenv(sysenv);
-               }
-               pat_tested = 1;
-       }
-
        /* Initialize default PAT entries. */
        pat_msr = PAT_VALUE(0, PAT_WRITE_BACK) |
            PAT_VALUE(1, PAT_WRITE_THROUGH) |
-           PAT_VALUE(2, PAT_UNCACHED) |
+           PAT_VALUE(2, PAT_WRITE_COMBINING) |
            PAT_VALUE(3, PAT_UNCACHEABLE) |
            PAT_VALUE(4, PAT_WRITE_BACK) |
            PAT_VALUE(5, PAT_WRITE_THROUGH) |
@@ -646,19 +629,10 @@ pmap_init_pat(void)
 
        if (pat_works) {
                /*
-                * Leave the indices 0-3 at the default of WB, WT, UC-, and UC.
-                * Program 4 and 5 as WP and WC.
-                * Leave 6 and 7 as UC- and UC.
+                * Just replace PAT Index 5 with WP instead of WT.
                 */
-               pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5));
-               pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) |
-                   PAT_VALUE(5, PAT_WRITE_COMBINING);
-       } else {
-               /*
-                * Just replace PAT Index 2 with WC instead of UC-.
-                */
-               pat_msr &= ~PAT_MASK(2);
-               pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
+               pat_msr &= ~PAT_MASK(5);
+               pat_msr |= PAT_VALUE(5, PAT_WRITE_PROTECTED);
        }
        wrmsr(MSR_PAT, pat_msr);
 }
@@ -829,13 +803,13 @@ pmap_cache_bits(int mode, boolean_t is_pde)
                        pat_index = 0;
                        break;
                case PAT_UNCACHED:
-                       pat_index = 2;
+                       pat_index = 6;
                        break;
                case PAT_WRITE_COMBINING:
-                       pat_index = 5;
+                       pat_index = 2;
                        break;
                case PAT_WRITE_PROTECTED:
-                       pat_index = 4;
+                       pat_index = 5;
                        break;
                default:
                        panic("Unknown caching mode %d\n", mode);
Index: sys/i386/i386/pmap.c
===================================================================
--- sys/i386/i386/pmap.c        (revision 215352)
+++ sys/i386/i386/pmap.c        (working copy)
@@ -217,10 +217,13 @@ pt_entry_t pg_nx;
 static uma_zone_t pdptzone;
 #endif
 
-static int pat_works = 0;              /* Is page attribute table sane? */
-
 SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
 
+static int pat_works = 1;
+TUNABLE_INT("vm.pmap.pat_works", &pat_works);
+SYSCTL_INT(_vm_pmap, OID_AUTO, pat_works, CTLFLAG_RDTUN, &pat_works, 1,
+    "Is page attribute table fully functional?");
+
 static int pg_ps_enabled = 1;
 SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RDTUN, &pg_ps_enabled, 0,
     "Are large page mappings enabled?");
@@ -491,12 +494,12 @@ void
 pmap_init_pat(void)
 {
        uint64_t pat_msr;
-       char *sysenv;
-       static int pat_tested = 0;
 
        /* Bail if this CPU doesn't implement PAT. */
-       if (!(cpu_feature & CPUID_PAT))
+       if (!(cpu_feature & CPUID_PAT)) {
+               pat_works = 0;
                return;
+       }
 
        /*
         * Due to some Intel errata, we can only safely use the lower 4
@@ -508,32 +511,15 @@ pmap_init_pat(void)
         *
         *   Intel Pentium IV  Processor Specification Update
         * Errata N46 (PAT Index MSB May Be Calculated Incorrectly)
-        *
-        * Some Apple Macs based on nVidia chipsets cannot enter ACPI mode
-        * via SMI# when we use upper 4 PAT entries for unknown reason.
         */
-       if (!pat_tested) {
-               if (cpu_vendor_id != CPU_VENDOR_INTEL ||
-                   (CPUID_TO_FAMILY(cpu_id) == 6 &&
-                   CPUID_TO_MODEL(cpu_id) >= 0xe)) {
-                       pat_works = 1;
-                       sysenv = getenv("smbios.system.product");
-                       if (sysenv != NULL) {
-                               if (strncmp(sysenv, "MacBook5,1", 10) == 0 ||
-                                   strncmp(sysenv, "MacBookPro5,5", 13) == 0 ||
-                                   strncmp(sysenv, "Macmini3,1", 10) == 0 ||
-                                   strncmp(sysenv, "iMac9,1", 7) == 0)
-                                       pat_works = 0;
-                               freeenv(sysenv);
-                       }
-               }
-               pat_tested = 1;
-       }
+       if (cpu_vendor_id == CPU_VENDOR_INTEL &&
+           !(CPUID_TO_FAMILY(cpu_id) == 6 && CPUID_TO_MODEL(cpu_id) >= 0xe))
+               pat_works = 0;
 
        /* Initialize default PAT entries. */
        pat_msr = PAT_VALUE(0, PAT_WRITE_BACK) |
            PAT_VALUE(1, PAT_WRITE_THROUGH) |
-           PAT_VALUE(2, PAT_UNCACHED) |
+           PAT_VALUE(2, PAT_WRITE_COMBINING) |
            PAT_VALUE(3, PAT_UNCACHEABLE) |
            PAT_VALUE(4, PAT_WRITE_BACK) |
            PAT_VALUE(5, PAT_WRITE_THROUGH) |
@@ -542,19 +528,10 @@ pmap_init_pat(void)
 
        if (pat_works) {
                /*
-                * Leave the indices 0-3 at the default of WB, WT, UC-, and UC.
-                * Program 4 and 5 as WP and WC.
-                * Leave 6 and 7 as UC- and UC.
+                * Just replace PAT Index 5 with WP instead of WT.
                 */
-               pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5));
-               pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) |
-                   PAT_VALUE(5, PAT_WRITE_COMBINING);
-       } else {
-               /*
-                * Just replace PAT Index 2 with WC instead of UC-.
-                */
-               pat_msr &= ~PAT_MASK(2);
-               pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
+               pat_msr &= ~PAT_MASK(5);
+               pat_msr |= PAT_VALUE(5, PAT_WRITE_PROTECTED);
        }
        wrmsr(MSR_PAT, pat_msr);
 }
@@ -825,13 +802,13 @@ pmap_cache_bits(int mode, boolean_t is_pde)
                        pat_index = 0;
                        break;
                case PAT_UNCACHED:
-                       pat_index = 2;
+                       pat_index = 6;
                        break;
                case PAT_WRITE_COMBINING:
-                       pat_index = 5;
+                       pat_index = 2;
                        break;
                case PAT_WRITE_PROTECTED:
-                       pat_index = 4;
+                       pat_index = 5;
                        break;
                default:
                        panic("Unknown caching mode %d\n", mode);
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to