From owner-freebsd-current@FreeBSD.ORG Tue Nov 16 01:37:10 2010 Return-Path: Delivered-To: freebsd-current@FreeBSD.org Received: from [127.0.0.1] (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by hub.freebsd.org (Postfix) with ESMTP id 406541065679; Tue, 16 Nov 2010 01:37:04 +0000 (UTC) (envelope-from jkim@FreeBSD.org) From: Jung-uk Kim To: freebsd-current@FreeBSD.org Date: Mon, 15 Nov 2010 20:36:42 -0500 User-Agent: KMail/1.6.2 MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_wAe4McdFcflp2mK" Message-Id: <201011152036.48181.jkim@FreeBSD.org> Cc: Ed Schouten , Hans Petter Selasky Subject: [Call for Tests] PAT issue on Apple hardware X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Nov 2010 01:37:10 -0000 --Boundary-00=_wAe4McdFcflp2mK Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 --Boundary-00=_wAe4McdFcflp2mK Content-Type: text/plain; charset="iso-8859-1"; name="pmap.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pmap.diff" 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); --Boundary-00=_wAe4McdFcflp2mK--