x86/xsave: Move xsave initialization to after parsing early parameters
PATCH 1/5 x86/xsave: Move xsave initialization to after parsing early parameters
From: Andi Kleen <[email protected]>
Move the XSAVE initialization code to be after parsing early parameters. I don't see any reason why the FPU code needs to be initialized that early, nothing else in the initialization phase uses XSAVE. This is useful to be able to handle command line parameters in the XSAVE initialization code.
--- arch/x86/kernel/cpu/common.c | 1 - arch/x86/kernel/setup.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-)
arch/x86/kernel/cpu/common.c +0 -1
@@ -885,7 +885,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) }setup_force_cpu_cap (X86_FEATURE_ALWAYS ); -fpu__init_system (c); }void __init early_cpu_init (void )
arch/x86/kernel/setup.c +3 -0
@@ -91,6 +91,7 @@#include <asm/processor.h> #include <asm/bugs.h> #include <asm/kasan.h> +#include <asm/fpu/internal.h> #include <asm/vsyscall.h> #include <asm/cpu.h>
@@ -982,6 +983,8 @@ void __init setup_arch(char **cmdline_p)parse_early_param (); +fpu__init_system (&boot_cpu_data); +#ifdef CONFIG_MEMORY_HOTPLUG /* * Memory used by the kernel cannot be hot-removed because Linux
Signature · 1 line
2.9.4
PATCH 2/5 x86/cpuid: Add generic table for cpuid dependencies
From: Andi Kleen <[email protected]>
Some CPUID features depend on other features. Currently it's possible to to clear dependent features, but not clear the base features, which can cause various interesting problems.
This patch implements a generic table to describe dependencies between CPUID features, to be used by all code that clears CPUID.
Some subsystems (like XSAVE) had an own implementation of this, but it's better to do it all in a single place for everyone.
Then clear_cpu_cap and setup_clear_cpu_cap always look up this table and clear all dependencies too.
This is intended to be a practical table: only for features that make sense to clear. If someone for example clears FPU, or other features that are essentially part of the required base feature set, not much is going to work. Handling that is right now out of scope. We're only handling features which can be usefully cleared.
--- arch/x86/include/asm/cpufeature.h | 8 +++- arch/x86/include/asm/cpufeatures.h | 5 +++ arch/x86/kernel/cpu/Makefile | 1 + arch/x86/kernel/cpu/cpuid-deps.c | 89 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 arch/x86/kernel/cpu/cpuid-deps.c
arch/x86/include/asm/cpufeature.h +6 -2
@@ -125,8 +125,12 @@ extern const char * const x86_bug_flags[NBUGINTS*32];#define boot_cpu_has (bit) cpu_has(&boot_cpu_data, bit)#define set_cpu_cap (c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability)) -#define clear_cpu_cap (c, bit) clear_bit(bit, (unsigned long *)((c)->x86_capability)) -#define setup_clear_cpu_cap (bit) do { \ +#define __clear_cpu_cap (c, bit) clear_bit(bit, (unsigned long *)((c)->x86_capability)) + +extern void setup_clear_cpu_cap (int bit); +extern void clear_cpu_cap (struct cpuinfo_x86 *cpu,int bit); + +#define __setup_clear_cpu_cap (bit) do { \ clear_cpu_cap(&boot_cpu_data, bit); \ set_bit(bit, (unsigned long *)cpu_caps_cleared); \ } while (0)
arch/x86/include/asm/cpufeatures.h +5 -0
@@ -21,6 +21,11 @@* this feature bit is not displayed in /proc/cpuinfo at all. */ +/* +* When adding new features here that depend on other features, +* please update the table in kernel/cpu/cpuid-deps.c +*/ +/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ #define X86_FEATURE_FPU ( 0*32+ 0)/* Onboard FPU */ #define X86_FEATURE_VME ( 0*32+ 1)/* Virtual Mode Extensions */
arch/x86/kernel/cpu/Makefile +1 -0
@@ -21,6 +21,7 @@ obj-y += common.o obj-y += rdrand.o obj-y += match.o obj-y += bugs.o +obj-y += cpuid-deps.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
arch/x86/kernel/cpu/cpuid-deps.c new file +89 -0
89 lines not on this page · raw message
Signature · 1 line
2.9.4
kbuild test robot
build botRe: [PATCH 2/5] x86/cpuid: Add generic table for cpuid dependencies
url: https://github.com/0day-ci/linux/commits/Andi-Kleen/x86-xsave-Move-xsave-initialization-to-after-parsing-early-parameters/20170601-085802 config: i386-randconfig-h0-06040930 (attached as…
Hi Andi,
[auto build test ERROR on tip/auto-latest]
[also build test ERROR on v4.12-rc3 next-20170602]
[cannot apply to tip/x86/core]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Andi-Kleen/x86-xsave-Move-xsave-initialization-to-after-parsing-early-parameters/20170601-085802
config: i386-randconfig-h0-06040930 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce:
# save the attached .config to linux build tree
make ARCH=i386 All errors (new ones prefixed by >>):
>> ERROR: "clear_cpu_cap" [drivers/lguest/lg.ko] undefined!
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Re: [PATCH 2/5] x86/cpuid: Add generic table for cpuid dependencies
Quoted 3 lines
All errors (new ones prefixed by >>):
Quoted 1 line
Quoted 1 line
ERROR: "
clear_cpu_cap" [drivers/lguest/lg.ko] undefined!
It looks very broken what lguest does here. But ok, we can add a EXPORT_SYMBOL.
-Andi
PATCH 3/5 x86/cpuid: Make clearcpuid an early param
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Make clearcpuid= an early param, to make sure it is parsed before the XSAVE initialization. This allows to modify XSAVE state by clearing specific CPUID bits.
--- arch/x86/kernel/cpu/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/common.c +1 -1
@@ -1285,7 +1285,7 @@ static __init int setup_disablecpuid(char *arg)return 1 ; } -__setup ("clearcpuid=" , setup_disablecpuid); +early_param ("clearcpuid" , setup_disablecpuid);#ifdef CONFIG_X86_64 struct desc_ptr idt_descr __ro_after_init = {
Signature · 1 line
2.9.4
PATCH 4/5 x86/xsave: Make XSAVE check the base CPUID features before enabling
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Before enabling XSAVE, not only check the XSAVE specific CPUID bits, but also the base CPUID features of the respective XSAVE feature. This allows to disable individual XSAVE states using the existing clearcpuid= option, and also in general avoids inconsistencies. For example some kernel code using XSAVE enabled features could currently crash when the underlying CPUID feature is not available.
--- arch/x86/kernel/fpu/xstate.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
arch/x86/kernel/fpu/xstate.c +22 -0
@@ -15,6 +15,7 @@#include <asm/fpu/xstate.h> #include <asm/tlbflush.h> +#include <asm/cpufeature.h> /* * Although we spell it out in here, the Processor Trace
@@ -36,6 +37,19 @@ static const char *xfeature_names[] = "unknown xstate feature" , }; +static short xsave_cpuid_features[] = { +X86_FEATURE_FPU , +X86_FEATURE_XMM , +X86_FEATURE_AVX , +X86_FEATURE_MPX , +X86_FEATURE_MPX , +X86_FEATURE_AVX512F , +X86_FEATURE_AVX512F , +X86_FEATURE_AVX512F , +X86_FEATURE_INTEL_PT , +X86_FEATURE_PKU , +}; +/* * Mask of xstate features supported by the CPU and the kernel: */
@@ -702,6 +716,7 @@ void __init fpu__init_system_xstate(void)unsigned int eax, ebx, ecx, edx;static int on_boot_cpu__initdata =1 ;int err; +int i;WARN_ON_FPU (!on_boot_cpu); on_boot_cpu =0 ;
@@ -735,6 +750,13 @@ void __init fpu__init_system_xstate(void) goto out_disable; } +/* +* Clear XSAVE features that are disabled in the normal CPUID. +*/ +for (i =0 ; i <ARRAY_SIZE (xsave_cpuid_features); i++) +if (!boot_cpu_has (xsave_cpuid_features[i])) + xfeatures_mask &= ~BIT (i); + xfeatures_mask &=fpu__get_supported_xfeatures_mask ();/* Enable xstate instructions to be able to continue with initialization: */
Signature · 1 line
2.9.4
PATCH 5/5 x86/xsave: Using generic CPUID clearing when disabling XSAVE
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Now that the generic CPUID clearing understands dependencies, it's enough to clear the XSAVE CPUID bit to clear all depending features when XSAVE gets disabled.
So we don't need this hard to maintain explicit list of features depending on XSAVE anymore. Just call the generic clear_cpu_cap() function for XSAVE.
--- arch/x86/kernel/fpu/xstate.c | 20 -------------------- 1 file changed, 20 deletions(-)
arch/x86/kernel/fpu/xstate.c +0 -20
@@ -73,26 +73,6 @@ unsigned int fpu_user_xstate_size;void fpu__xstate_clear_all_cpu_caps (void ) {setup_clear_cpu_cap (X86_FEATURE_XSAVE ); -setup_clear_cpu_cap (X86_FEATURE_XSAVEOPT ); -setup_clear_cpu_cap (X86_FEATURE_XSAVEC ); -setup_clear_cpu_cap (X86_FEATURE_XSAVES ); -setup_clear_cpu_cap (X86_FEATURE_AVX ); -setup_clear_cpu_cap (X86_FEATURE_AVX2 ); -setup_clear_cpu_cap (X86_FEATURE_AVX512F ); -setup_clear_cpu_cap (X86_FEATURE_AVX512IFMA ); -setup_clear_cpu_cap (X86_FEATURE_AVX512PF ); -setup_clear_cpu_cap (X86_FEATURE_AVX512ER ); -setup_clear_cpu_cap (X86_FEATURE_AVX512CD ); -setup_clear_cpu_cap (X86_FEATURE_AVX512DQ ); -setup_clear_cpu_cap (X86_FEATURE_AVX512BW ); -setup_clear_cpu_cap (X86_FEATURE_AVX512VL ); -setup_clear_cpu_cap (X86_FEATURE_MPX ); -setup_clear_cpu_cap (X86_FEATURE_XGETBV1 ); -setup_clear_cpu_cap (X86_FEATURE_AVX512VBMI ); -setup_clear_cpu_cap (X86_FEATURE_PKU ); -setup_clear_cpu_cap (X86_FEATURE_AVX512_4VNNIW ); -setup_clear_cpu_cap (X86_FEATURE_AVX512_4FMAPS ); -setup_clear_cpu_cap (X86_FEATURE_AVX512_VPOPCNTDQ ); }/*
Signature · 1 line
2.9.4