Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757400AbdDRTHR (ORCPT ); Tue, 18 Apr 2017 15:07:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59630 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753430AbdDRTHO (ORCPT ); Tue, 18 Apr 2017 15:07:14 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3C32985376 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=mpatocka@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3C32985376 Date: Tue, 18 Apr 2017 15:07:11 -0400 (EDT) From: Mikulas Patocka X-X-Sender: mpatocka@file01.intranet.prod.int.rdu2.redhat.com To: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" cc: x86@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] X86: don't report PAT on CPUs that don't support it Message-ID: User-Agent: Alpine 2.02 (LRH 1266 2009-07-14) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 18 Apr 2017 19:07:14 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3556 Lines: 91 In the file arch/x86/mm/pat.c, there's a variable __pat_enabled. The variable is set to 1 by default and the function pat_init() sets __pat_enabled to 0 if the CPU doesn't support PAT. However, on AMD K6-3 CPU, the processor initialization code never calls pat_init() and so __pat_enabled stays 1 and the function pat_enabled() returns true, even though the K6-3 CPU doesn't support PAT. The result of this bug is that this warning is produced when attemting to start the Xserver and the Xserver doesn't start (fork() returns ENOMEM). Another symptom of this bug is that the framebuffer driver doesn't set the K6-3 MTRR registers. This patch changes pat_enabled() so that it returns true only if pat initialization was actually done. Also, I changed boot_cpu_has(X86_FEATURE_PAT) to this_cpu_has(X86_FEATURE_PAT) in pat_ap_init, so that we check the PAT feature on the processor that is being initialized. x86/PAT: Xorg:3891 map pfn expected mapping type uncached-minus for [mem 0xe4000000-0xe5ffffff], got write-combining ------------[ cut here ]------------ WARNING: CPU: 0 PID: 3891 at arch/x86/mm/pat.c:1020 untrack_pfn+0x5c/0x9f Modules linked in: blowfish_generic blowfish_common cbc dm_crypt dm_loop msr configfs cpufreq_userspace cpufreq_powersave cpufreq_ondemand cpufreq_conservative ext4 crc16 jbd2 mbcache hpfs nls_cp852 msdos fat matroxfb_base matroxfb_g450 matroxfb_accel cfbfillrect cfbimgblt cfbcopyarea matroxfb_DAC1064 g450_pll matroxfb_misc floppy snd_usb_audio snd_hwdep snd_usbmidi_lib snd_seq_midi snd_seq_midi_event snd_rawmidi snd_pcm snd_seq snd_seq_device snd_timer hid_generic snd usbhid hid soundcore powernow_k6 pcspkr evdev e1000 ehci_pci uhci_hcd ehci_hcd usbcore usb_common dm_mod pata_it821x unix CPU: 0 PID: 3891 Comm: Xorg Not tainted 4.11.0-rc6-test+ #35 Hardware name: System Manufacturer Product Name/VA-503A, BIOS 4.51 PG 08/02/00 Call Trace: ? __warn+0xab/0xc0 ? untrack_pfn+0x5c/0x9f ? warn_slowpath_null+0xf/0x13 ? untrack_pfn+0x5c/0x9f ? unmap_single_vma+0x43/0x66 ? unmap_vmas+0x24/0x30 ? exit_mmap+0x3c/0xa5 ? __mmput+0xf/0x76 ? copy_process.part.76+0xb43/0x1129 ? _do_fork+0x96/0x177 ? do_int80_syscall_32+0x3e/0x4c ? entry_INT80_32+0x2a/0x2a ---[ end trace 8726f9d9fa90d702 ]--- x86/PAT: Xorg:3891 map pfn expected mapping type uncached-minus for [mem 0xe4000000-0xe5ffffff], got write-combining Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org # v4.2+ --- arch/x86/mm/pat.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) Index: linux-2.6/arch/x86/mm/pat.c =================================================================== --- linux-2.6.orig/arch/x86/mm/pat.c +++ linux-2.6/arch/x86/mm/pat.c @@ -64,9 +64,11 @@ static int __init nopat(char *str) } early_param("nopat", nopat); +static bool __read_mostly __pat_initialized = false; + bool pat_enabled(void) { - return !!__pat_enabled; + return __pat_initialized; } EXPORT_SYMBOL_GPL(pat_enabled); @@ -224,13 +226,14 @@ static void pat_bsp_init(u64 pat) } wrmsrl(MSR_IA32_CR_PAT, pat); + __pat_initialized = true; __init_cache_modes(pat); } static void pat_ap_init(u64 pat) { - if (!boot_cpu_has(X86_FEATURE_PAT)) { + if (!this_cpu_has(X86_FEATURE_PAT)) { /* * If this happens we are on a secondary CPU, but switched to * PAT on the boot CPU. We have no way to undo PAT. @@ -305,7 +308,7 @@ void pat_init(void) u64 pat; struct cpuinfo_x86 *c = &boot_cpu_data; - if (!pat_enabled()) { + if (!__pat_enabled) { init_cache_modes(); return; }