Skip to contentSkip to conversation

x86/xsave: Move xsave initialization to after parsing early parameters

PATCH In review Andi Kleen 2 participants 3 messages Mar 11, 2017 – Apr 19, 2017

Subsystems (2)
lore
Share & tools
lore

Andi Kleen

author
#0 lore raw

PATCH 1/2 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
index 58094a1f9e9d..db16a28d49a1 100644
@@ -844,7 +844,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
index 4bf0c8926a1c..2a85efc37e1f 100644
@@ -90,6 +90,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>
@@ -987,6 +988,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.3
author
#1 lore raw

PATCH 2/2 x86/fpu: Support disabling AVX and AVX512

From: Andi Kleen <[email protected]>

For performance testing it is useful to be able to disable AVX and AVX512. User programs check in XGETBV if AVX is supported by the OS. If we don't initialize the XSAVE state for AVX it will appear as if the OS is not supporting AVX.

Implement disable options for AVX and AVX512 code in the XSAVE code.

v2: Change description. Make variable static. Remove Intel reference.

---
 Documentation/admin-guide/kernel-parameters.txt |  3 ++
 arch/x86/kernel/fpu/xstate.c                    | 61 +++++++++++++++++++++----
 2 files changed, 55 insertions(+), 9 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +3 -0
index 2ba45caabada..b94ff507a48f 100644
@@ -785,6 +785,9 @@
 	dhash_entries=	[KNL]
 			Set number of hash buckets for dentry cache.
 
+	disable_avx	[X86] Disable support for AVX
+	disable_avx512	[X86] Disable support for AVX512
+
 	disable_1tb_segments [PPC]
 			Disables the use of 1TB hash page table segments. This
 			causes the kernel to fall back to 256MB segments which
arch/x86/kernel/fpu/xstate.c +52 -9

96 lines not on this page · raw message

Signature · 1 line
2.9.3
#2 lore raw

Re: [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512

Ping! Any comments on these patches? If ok please consider merging.

Thanks,
-Andi

Quoted 139 lines · Andi Kleen

From: Andi Kleen <[email protected]>

For performance testing it is useful to be able to disable AVX and AVX512. User programs check in XGETBV if AVX is supported by the OS. If we don't initialize the XSAVE state for AVX it will appear as if the OS is not supporting AVX.

Implement disable options for AVX and AVX512 code in the XSAVE code.

v2: Change description. Make variable static. Remove Intel reference.

---
 Documentation/admin-guide/kernel-parameters.txt |  3 ++
 arch/x86/kernel/fpu/xstate.c                    | 61 +++++++++++++++++++++----
 2 files changed, 55 insertions(+), 9 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +3 -0
index 2ba45caabada..b94ff507a48f 100644
@@ -785,6 +785,9 @@
 	dhash_entries=	[KNL]
 			Set number of hash buckets for dentry cache.
 
+	disable_avx	[X86] Disable support for AVX
+	disable_avx512	[X86] Disable support for AVX512
+
 	disable_1tb_segments [PPC]
 			Disables the use of 1TB hash page table segments. This
 			causes the kernel to fall back to 256MB segments which
arch/x86/kernel/fpu/xstate.c +52 -9
index c24ac1efb12d..977ab03eacf7 100644
@@ -16,6 +16,20 @@
 
 #include <asm/tlbflush.h>
 
+enum xsave_features {
+	XSAVE_X87,
+	XSAVE_SSE,
+	XSAVE_AVX,
+	XSAVE_MPX_BOUNDS,
+	XSAVE_MPX_CSR,
+	XSAVE_AVX512_OPMASK,
+	XSAVE_AVX512_HI256,
+	XSAVE_AVX512_ZMM_HI256,
+	XSAVE_PT,
+	XSAVE_PKU,
+	XSAVE_UNKNOWN
+};
+
 /*
  * Although we spell it out in here, the Processor Trace
  * xfeature is completely unused.  We use other mechanisms
@@ -41,6 +55,8 @@ static const char *xfeature_names[] =
  */
 u64 xfeatures_mask __read_mostly;
 
+static u64 xfeatures_disabled __initdata;
+
 static unsigned int xstate_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1};
 static unsigned int xstate_sizes[XFEATURE_MAX]   = { [ 0 ... XFEATURE_MAX - 1] = -1};
 static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
@@ -52,6 +68,21 @@ static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
  */
 unsigned int fpu_user_xstate_size;
 
+static void clear_avx512(void)
+{
+	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_AVX512VBMI);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512_4VNNIW);
+	setup_clear_cpu_cap(X86_FEATURE_AVX512_4FMAPS);
+}
+
 /*
  * Clear all of the X86_FEATURE_* bits that are unavailable
  * when the CPU has no XSAVE support.
@@ -64,17 +95,9 @@ void fpu__xstate_clear_all_cpu_caps(void)
 	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);
+	clear_avx512();
 	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);
@@ -735,6 +758,7 @@ void __init fpu__init_system_xstate(void)
 		goto out_disable;
 	}
 
+	xfeatures_mask &= ~xfeatures_disabled;
 	xfeatures_mask &= fpu__get_supported_xfeatures_mask();
 
 	/* Enable xstate instructions to be able to continue with initialization: */
@@ -1080,3 +1104,22 @@ int copyin_to_xsaves(const void *kbuf, const void __user *ubuf,
 
 	return 0;
 }
+
+static int __init parse_disable_avx512(char *str)
+{
+	xfeatures_disabled |= BIT(XSAVE_AVX512_OPMASK) |
+			      BIT(XSAVE_AVX512_HI256) |
+			      BIT(XSAVE_AVX512_ZMM_HI256);
+	clear_avx512();
+	return 0;
+}
+early_param("disable_avx512", parse_disable_avx512);
+
+static int __init parse_disable_avx(char *str)
+{
+	xfeatures_disabled |= BIT(XSAVE_AVX);
+	setup_clear_cpu_cap(X86_FEATURE_AVX);
+	setup_clear_cpu_cap(X86_FEATURE_AVX2);
+	return parse_disable_avx512(NULL);
+}
+early_param("disable_avx", parse_disable_avx);
Signature · 1 line
2.9.3