linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] x86/xsave: Move xsave initialization to after parsing early parameters
@ 2017-03-11 17:30 Andi Kleen
  2017-03-11 17:30 ` [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512 Andi Kleen
  0 siblings, 1 reply; 7+ messages in thread
From: Andi Kleen @ 2017-03-11 17:30 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

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.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/common.c | 1 -
 arch/x86/kernel/setup.c      | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 58094a1f9e9d..db16a28d49a1 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -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)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 4bf0c8926a1c..2a85efc37e1f 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -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
-- 
2.9.3

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512
  2017-03-11 17:30 [PATCH 1/2] x86/xsave: Move xsave initialization to after parsing early parameters Andi Kleen
@ 2017-03-11 17:30 ` Andi Kleen
  2017-04-19 23:03   ` Andi Kleen
  0 siblings, 1 reply; 7+ messages in thread
From: Andi Kleen @ 2017-03-11 17:30 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

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.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 Documentation/admin-guide/kernel-parameters.txt |  3 ++
 arch/x86/kernel/fpu/xstate.c                    | 61 +++++++++++++++++++++----
 2 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 2ba45caabada..b94ff507a48f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -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
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index c24ac1efb12d..977ab03eacf7 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -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);
-- 
2.9.3

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512
  2017-03-11 17:30 ` [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512 Andi Kleen
@ 2017-04-19 23:03   ` Andi Kleen
  0 siblings, 0 replies; 7+ messages in thread
From: Andi Kleen @ 2017-04-19 23:03 UTC (permalink / raw)
  To: Andi Kleen; +Cc: x86, linux-kernel

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

Thanks,
-Andi

On Sat, Mar 11, 2017 at 09:30:57AM -0800, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
> 
> 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.
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> ---
>  Documentation/admin-guide/kernel-parameters.txt |  3 ++
>  arch/x86/kernel/fpu/xstate.c                    | 61 +++++++++++++++++++++----
>  2 files changed, 55 insertions(+), 9 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 2ba45caabada..b94ff507a48f 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -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
> diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
> index c24ac1efb12d..977ab03eacf7 100644
> --- a/arch/x86/kernel/fpu/xstate.c
> +++ b/arch/x86/kernel/fpu/xstate.c
> @@ -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);
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512
  2017-03-11 17:20     ` Andi Kleen
@ 2017-03-12 17:30       ` Thomas Gleixner
  0 siblings, 0 replies; 7+ messages in thread
From: Thomas Gleixner @ 2017-03-12 17:30 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Andi Kleen, x86, linux-kernel

On Sat, 11 Mar 2017, Andi Kleen wrote:

> On Sat, Mar 11, 2017 at 11:46:37AM +0100, Thomas Gleixner wrote:
> > > +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
> > > +};
> > 
> > What's that enum for? It's unused ....
> 
> It's not.  The disable functions use it (although only the AVX parts)

Sorry, misread it.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512
  2017-03-11 10:46   ` Thomas Gleixner
@ 2017-03-11 17:20     ` Andi Kleen
  2017-03-12 17:30       ` Thomas Gleixner
  0 siblings, 1 reply; 7+ messages in thread
From: Andi Kleen @ 2017-03-11 17:20 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: Andi Kleen, x86, linux-kernel

On Sat, Mar 11, 2017 at 11:46:37AM +0100, Thomas Gleixner wrote:
> > +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
> > +};
> 
> What's that enum for? It's unused ....

It's not.  The disable functions use it (although only the AVX parts)

-Andi

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512
  2017-03-11  0:32 ` [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512 Andi Kleen
@ 2017-03-11 10:46   ` Thomas Gleixner
  2017-03-11 17:20     ` Andi Kleen
  0 siblings, 1 reply; 7+ messages in thread
From: Thomas Gleixner @ 2017-03-11 10:46 UTC (permalink / raw)
  To: Andi Kleen; +Cc: x86, linux-kernel, Andi Kleen

On Fri, 10 Mar 2017, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
> 
> 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. For kernel users we
> can also clear the internal cpu feature bits.
> 
> This patch implements disable options for AVX and AVX512 for
> the XSAVE code.
>
> I originally considered a generic argument that would disable
> any XSAVE feature, but it turns out you need special code
> to also disable all the CPUID bits, because otherwise
> kernel code may assume it exists, when it doesn't. MPX
> already has an own disable flag. Not clear it is useful
> for the others. So we only do it for AVX/AVX512 for now.

Please read and follow Documentation/process/submitting-patches.rst.

Especially this paragraph:

   Describe your changes in imperative mood, e.g. "make xyzzy do frotz"
   instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy
   to do frotz", as if you are giving orders to the codebase to change
   its behaviour.


> +	disable_avx	[X86] Disable support for AVX on Intel CPUs.

So that command line option fails on AMD CPUs, right?

> +	disable_avx512	[X86] Disable support for AVX512 on Intel CPUs.

Please drop the Intel stuff here as well. It's just a question of time
until AMD gets that as well.

>  	disable_1tb_segments [PPC]
>  			Disables the use of 1TB hash page table segments. This
>  			causes the kernel to fall back to 256MB segments which
> diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
> index c24ac1efb12d..cf75638ec657 100644
> --- a/arch/x86/kernel/fpu/xstate.c
> +++ b/arch/x86/kernel/fpu/xstate.c
> @@ -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
> +};

What's that enum for? It's unused ....

>  /*
>   * 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;
>  
> +u64 xfeatures_disabled __initdata;

Why is this global?

> +	xfeatures_mask &= ~xfeatures_disabled;
>  	xfeatures_mask &= fpu__get_supported_xfeatures_mask();

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512
  2017-03-11  0:32 [PATCH 1/2] x86/xsave: Move xsave initialization to after parsing early parameters Andi Kleen
@ 2017-03-11  0:32 ` Andi Kleen
  2017-03-11 10:46   ` Thomas Gleixner
  0 siblings, 1 reply; 7+ messages in thread
From: Andi Kleen @ 2017-03-11  0:32 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

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. For kernel users we
can also clear the internal cpu feature bits.

This patch implements disable options for AVX and AVX512 for
the XSAVE code.

I originally considered a generic argument that would disable
any XSAVE feature, but it turns out you need special code
to also disable all the CPUID bits, because otherwise
kernel code may assume it exists, when it doesn't. MPX
already has an own disable flag. Not clear it is useful
for the others. So we only do it for AVX/AVX512 for now.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 Documentation/admin-guide/kernel-parameters.txt |  3 ++
 arch/x86/kernel/fpu/xstate.c                    | 61 +++++++++++++++++++++----
 2 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 2ba45caabada..d9ae4a2c07ab 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -785,6 +785,9 @@
 	dhash_entries=	[KNL]
 			Set number of hash buckets for dentry cache.
 
+	disable_avx	[X86] Disable support for AVX on Intel CPUs.
+	disable_avx512	[X86] Disable support for AVX512 on Intel CPUs.
+
 	disable_1tb_segments [PPC]
 			Disables the use of 1TB hash page table segments. This
 			causes the kernel to fall back to 256MB segments which
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index c24ac1efb12d..cf75638ec657 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -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;
 
+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);
-- 
2.9.3

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-04-19 23:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-11 17:30 [PATCH 1/2] x86/xsave: Move xsave initialization to after parsing early parameters Andi Kleen
2017-03-11 17:30 ` [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512 Andi Kleen
2017-04-19 23:03   ` Andi Kleen
  -- strict thread matches above, loose matches on Subject: below --
2017-03-11  0:32 [PATCH 1/2] x86/xsave: Move xsave initialization to after parsing early parameters Andi Kleen
2017-03-11  0:32 ` [PATCH 2/2] x86/fpu: Support disabling AVX and AVX512 Andi Kleen
2017-03-11 10:46   ` Thomas Gleixner
2017-03-11 17:20     ` Andi Kleen
2017-03-12 17:30       ` Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).