Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753095AbcLGJmh (ORCPT ); Wed, 7 Dec 2016 04:42:37 -0500 Received: from mail.skyhub.de ([78.46.96.112]:39012 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753052AbcLGJmg (ORCPT ); Wed, 7 Dec 2016 04:42:36 -0500 Date: Wed, 7 Dec 2016 10:42:29 +0100 From: Borislav Petkov To: Andy Lutomirski Cc: Andy Lutomirski , X86 ML , One Thousand Gnomes , "linux-kernel@vger.kernel.org" , Brian Gerst , Matthew Whitehead Subject: Re: [RFC PATCH 5/6] x86/fpu: Fix CPUID-less FPU detection Message-ID: <20161207094229.gxqatdjulfvnz7eo@pd.tnic> References: <20161206094000.ql5gjky7ag3b6j7v@pd.tnic> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20161014 (1.7.1) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2345 Lines: 78 On Tue, Dec 06, 2016 at 09:52:11AM -0800, Andy Lutomirski wrote: > How? There's that bit at the bottom to worry about. Even better: carve it out into a separate function. It was begging for it already. Diff ontop of yours: --- Index: b/arch/x86/kernel/fpu/init.c =================================================================== --- a/arch/x86/kernel/fpu/init.c 2016-12-07 10:39:57.643083996 +0100 +++ b/arch/x86/kernel/fpu/init.c 2016-12-07 10:39:45.807083690 +0100 @@ -49,31 +49,37 @@ void fpu__init_cpu(void) } /* - * The earliest FPU detection code. + * Try to execute an actual sequence of FPU instructions. Our last resort for + * FPU detection in case the respective CPUID bit is not set or we don't + * support CPUID at all. */ -static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) +static bool __fpu__init_poke_fpu(void) { - if (!boot_cpu_has(X86_FEATURE_CPUID) && - !test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { - /* - * Set the X86_FEATURE_FPU CPU-capability bit based on - * trying to execute an actual sequence of FPU instructions: - */ + unsigned long cr0; + u16 fsw, fcw; - unsigned long cr0; - u16 fsw, fcw; + fsw = fcw = 0xffff; - fsw = fcw = 0xffff; + cr0 = read_cr0(); + cr0 &= ~(X86_CR0_TS | X86_CR0_EM); + write_cr0(cr0); - cr0 = read_cr0(); - cr0 &= ~(X86_CR0_TS | X86_CR0_EM); - write_cr0(cr0); + 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: FSW=0x%04hx FCW=0x%04hx\n", fsw, fcw); + pr_info("x86/fpu: FSW=0x%04hx FCW=0x%04hx\n", fsw, fcw); - if (fsw == 0 && (fcw & 0x103f) == 0x003f) + return fsw == 0 && (fcw & 0x103f) == 0x003f; +} + +/* + * The earliest FPU detection code. + */ +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__init_poke_fpu()) setup_force_cpu_cap(X86_FEATURE_FPU); else setup_clear_cpu_cap(X86_FEATURE_FPU); > I kind of line the idea of being able to ask users of these ancient > CPUs to just send in their logs. Prudent :) -- Regards/Gruss, Boris. Good mailing practices for 400: avoid top-posting and trim the reply.