From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751841AbdAYLnw (ORCPT ); Wed, 25 Jan 2017 06:43:52 -0500 Received: from terminus.zytor.com ([65.50.211.136]:49240 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751414AbdAYLnu (ORCPT ); Wed, 25 Jan 2017 06:43:50 -0500 Date: Wed, 25 Jan 2017 03:42:33 -0800 From: tip-bot for Andy Lutomirski Message-ID: Cc: peterz@infradead.org, yu-cheng.yu@intel.com, torvalds@linux-foundation.org, tedheadster@gmail.com, gnomes@lxorguk.ukuu.org.uk, brgerst@gmail.com, bp@suse.de, tglx@linutronix.de, riel@redhat.com, oleg@redhat.com, dave.hansen@linux.intel.com, luto@kernel.org, bp@alien8.de, fenghua.yu@intel.com, hpa@zytor.com, mingo@kernel.org, linux-kernel@vger.kernel.org Reply-To: riel@redhat.com, luto@kernel.org, oleg@redhat.com, dave.hansen@linux.intel.com, fenghua.yu@intel.com, bp@alien8.de, linux-kernel@vger.kernel.org, mingo@kernel.org, hpa@zytor.com, peterz@infradead.org, torvalds@linux-foundation.org, tedheadster@gmail.com, gnomes@lxorguk.ukuu.org.uk, yu-cheng.yu@intel.com, brgerst@gmail.com, tglx@linutronix.de, bp@suse.de In-Reply-To: References: To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/fpu] x86/fpu: Fix CPUID-less FPU detection Git-Commit-ID: 37ac78b67b3384d1ced5424d5a13ee146041bda3 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 37ac78b67b3384d1ced5424d5a13ee146041bda3 Gitweb: http://git.kernel.org/tip/37ac78b67b3384d1ced5424d5a13ee146041bda3 Author: Andy Lutomirski AuthorDate: Wed, 18 Jan 2017 11:15:41 -0800 Committer: Ingo Molnar CommitDate: Wed, 25 Jan 2017 10:12:43 +0100 x86/fpu: Fix CPUID-less FPU detection The old code didn't work at all because it adjusted the current caps instead of the forced caps. Anything it did would be undone later during CPU identification. Fix that and, while we're at it, improve the logging and don't bother running it if CPUID is available. Reported-by: Matthew Whitehead Signed-off-by: Andy Lutomirski Reviewed-by: Borislav Petkov Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Hansen Cc: Fenghua Yu Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: One Thousand Gnomes Cc: Peter Zijlstra Cc: Rik van Riel Cc: Thomas Gleixner Cc: Yu-cheng Yu Link: http://lkml.kernel.org/r/f1134e30cafa73c4e2e68119e9741793622cfd15.1484705016.git.luto@kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/fpu/init.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 60dece3..8b526c5 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -48,13 +48,7 @@ void fpu__init_cpu(void) fpu__init_cpu_xstate(); } -/* - * The earliest FPU detection code. - * - * Set the X86_FEATURE_FPU CPU-capability bit based on - * trying to execute an actual sequence of FPU instructions: - */ -static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) +static bool fpu__probe_without_cpuid(void) { unsigned long cr0; u16 fsw, fcw; @@ -65,14 +59,21 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) cr0 &= ~(X86_CR0_TS | X86_CR0_EM); write_cr0(cr0); - if (!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { - asm volatile("fninit ; fnstsw %0 ; fnstcw %1" - : "+m" (fsw), "+m" (fcw)); + asm volatile("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw)); + + pr_info("x86/fpu: Probing for FPU: FSW=0x%04hx FCW=0x%04hx\n", fsw, fcw); - if (fsw == 0 && (fcw & 0x103f) == 0x003f) - set_cpu_cap(c, X86_FEATURE_FPU); + return fsw == 0 && (fcw & 0x103f) == 0x003f; +} + +static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) +{ + if (!boot_cpu_has(X86_FEATURE_CPUID) && + !test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { + if (fpu__probe_without_cpuid()) + setup_force_cpu_cap(X86_FEATURE_FPU); else - clear_cpu_cap(c, X86_FEATURE_FPU); + setup_clear_cpu_cap(X86_FEATURE_FPU); } #ifndef CONFIG_MATH_EMULATION