2017-10-13 21:56:42 +00:00
|
|
|
/* Declare dependencies between CPUIDs */
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <asm/cpufeature.h>
|
|
|
|
|
|
|
|
struct cpuid_dep {
|
|
|
|
unsigned int feature;
|
|
|
|
unsigned int depends;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Table of CPUID features that depend on others.
|
|
|
|
*
|
|
|
|
* This only includes dependencies that can be usefully disabled, not
|
|
|
|
* features part of the base set (like FPU).
|
|
|
|
*
|
|
|
|
* Note this all is not __init / __initdata because it can be
|
|
|
|
* called from cpu hotplug. It shouldn't do anything in this case,
|
|
|
|
* but it's difficult to tell that to the init reference checker.
|
|
|
|
*/
|
2018-03-07 16:07:34 +00:00
|
|
|
static const struct cpuid_dep cpuid_deps[] = {
|
x86/fpu: Make 'no387' and 'nofxsr' command line options useful
The command line option `no387' is designed to disable the FPU
entirely. This only 'works' with CONFIG_MATH_EMULATION enabled.
But on 64bit this cannot work because user space expects SSE to work which
required basic FPU support. MATH_EMULATION does not help because SSE is not
emulated.
The command line option `nofxsr' should also be limited to 32bit because
FXSR is part of the required flags on 64bit so turning it off is not
possible.
Clearing X86_FEATURE_FPU without emulation enabled will not work anyway and
hang in fpu__init_system_early_generic() before the console is enabled.
Setting additioal dependencies, ensures that the CPU still boots on a
modern CPU. Otherwise, dropping FPU will leave FXSR enabled causing the
kernel to crash early in fpu__init_system_mxcsr().
With XSAVE support it will crash in fpu__init_cpu_xstate(). The problem is
that xsetbv() with XMM set and SSE cleared is not allowed. That means
XSAVE has to be disabled. The XSAVE support is disabled in
fpu__init_system_xstate_size_legacy() but it is too late. It can be
removed, it has been added in commit
1f999ab5a1360 ("x86, xsave: Disable xsave in i387 emulation mode")
to use `no387' on a CPU with XSAVE support.
All this happens before console output.
After hat, the next possible crash is in RAID6 detect code because MMX
remained enabled. With a 3DNOW enabled config it will explode in memcpy()
for instance due to kernel_fpu_begin() but this is unconditionally enabled.
This is enough to boot a Debian Wheezy on a 32bit qemu "host" CPU which
supports everything up to XSAVES, AVX2 without 3DNOW. Later, Debian
increased the minimum requirements to i686 which means it does not boot
userland atleast due to CMOV.
After masking the additional features it still keeps SSE4A and 3DNOW*
enabled (if present on the host) but those are unused in the kernel.
Restrict `no387' and `nofxsr' otions to 32bit only. Add dependencies for
FPU, FXSR to additionaly mask CMOV, MMX, XSAVE if FXSR or FPU is cleared.
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20190703083247.57kjrmlxkai3vpw3@linutronix.de
2019-07-03 08:32:47 +00:00
|
|
|
{ X86_FEATURE_FXSR, X86_FEATURE_FPU },
|
2017-10-13 21:56:42 +00:00
|
|
|
{ X86_FEATURE_XSAVEOPT, X86_FEATURE_XSAVE },
|
|
|
|
{ X86_FEATURE_XSAVEC, X86_FEATURE_XSAVE },
|
|
|
|
{ X86_FEATURE_XSAVES, X86_FEATURE_XSAVE },
|
|
|
|
{ X86_FEATURE_AVX, X86_FEATURE_XSAVE },
|
|
|
|
{ X86_FEATURE_PKU, X86_FEATURE_XSAVE },
|
|
|
|
{ X86_FEATURE_MPX, X86_FEATURE_XSAVE },
|
|
|
|
{ X86_FEATURE_XGETBV1, X86_FEATURE_XSAVE },
|
x86/fpu: Make 'no387' and 'nofxsr' command line options useful
The command line option `no387' is designed to disable the FPU
entirely. This only 'works' with CONFIG_MATH_EMULATION enabled.
But on 64bit this cannot work because user space expects SSE to work which
required basic FPU support. MATH_EMULATION does not help because SSE is not
emulated.
The command line option `nofxsr' should also be limited to 32bit because
FXSR is part of the required flags on 64bit so turning it off is not
possible.
Clearing X86_FEATURE_FPU without emulation enabled will not work anyway and
hang in fpu__init_system_early_generic() before the console is enabled.
Setting additioal dependencies, ensures that the CPU still boots on a
modern CPU. Otherwise, dropping FPU will leave FXSR enabled causing the
kernel to crash early in fpu__init_system_mxcsr().
With XSAVE support it will crash in fpu__init_cpu_xstate(). The problem is
that xsetbv() with XMM set and SSE cleared is not allowed. That means
XSAVE has to be disabled. The XSAVE support is disabled in
fpu__init_system_xstate_size_legacy() but it is too late. It can be
removed, it has been added in commit
1f999ab5a1360 ("x86, xsave: Disable xsave in i387 emulation mode")
to use `no387' on a CPU with XSAVE support.
All this happens before console output.
After hat, the next possible crash is in RAID6 detect code because MMX
remained enabled. With a 3DNOW enabled config it will explode in memcpy()
for instance due to kernel_fpu_begin() but this is unconditionally enabled.
This is enough to boot a Debian Wheezy on a 32bit qemu "host" CPU which
supports everything up to XSAVES, AVX2 without 3DNOW. Later, Debian
increased the minimum requirements to i686 which means it does not boot
userland atleast due to CMOV.
After masking the additional features it still keeps SSE4A and 3DNOW*
enabled (if present on the host) but those are unused in the kernel.
Restrict `no387' and `nofxsr' otions to 32bit only. Add dependencies for
FPU, FXSR to additionaly mask CMOV, MMX, XSAVE if FXSR or FPU is cleared.
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20190703083247.57kjrmlxkai3vpw3@linutronix.de
2019-07-03 08:32:47 +00:00
|
|
|
{ X86_FEATURE_CMOV, X86_FEATURE_FXSR },
|
|
|
|
{ X86_FEATURE_MMX, X86_FEATURE_FXSR },
|
|
|
|
{ X86_FEATURE_MMXEXT, X86_FEATURE_MMX },
|
2017-10-13 21:56:42 +00:00
|
|
|
{ X86_FEATURE_FXSR_OPT, X86_FEATURE_FXSR },
|
x86/fpu: Make 'no387' and 'nofxsr' command line options useful
The command line option `no387' is designed to disable the FPU
entirely. This only 'works' with CONFIG_MATH_EMULATION enabled.
But on 64bit this cannot work because user space expects SSE to work which
required basic FPU support. MATH_EMULATION does not help because SSE is not
emulated.
The command line option `nofxsr' should also be limited to 32bit because
FXSR is part of the required flags on 64bit so turning it off is not
possible.
Clearing X86_FEATURE_FPU without emulation enabled will not work anyway and
hang in fpu__init_system_early_generic() before the console is enabled.
Setting additioal dependencies, ensures that the CPU still boots on a
modern CPU. Otherwise, dropping FPU will leave FXSR enabled causing the
kernel to crash early in fpu__init_system_mxcsr().
With XSAVE support it will crash in fpu__init_cpu_xstate(). The problem is
that xsetbv() with XMM set and SSE cleared is not allowed. That means
XSAVE has to be disabled. The XSAVE support is disabled in
fpu__init_system_xstate_size_legacy() but it is too late. It can be
removed, it has been added in commit
1f999ab5a1360 ("x86, xsave: Disable xsave in i387 emulation mode")
to use `no387' on a CPU with XSAVE support.
All this happens before console output.
After hat, the next possible crash is in RAID6 detect code because MMX
remained enabled. With a 3DNOW enabled config it will explode in memcpy()
for instance due to kernel_fpu_begin() but this is unconditionally enabled.
This is enough to boot a Debian Wheezy on a 32bit qemu "host" CPU which
supports everything up to XSAVES, AVX2 without 3DNOW. Later, Debian
increased the minimum requirements to i686 which means it does not boot
userland atleast due to CMOV.
After masking the additional features it still keeps SSE4A and 3DNOW*
enabled (if present on the host) but those are unused in the kernel.
Restrict `no387' and `nofxsr' otions to 32bit only. Add dependencies for
FPU, FXSR to additionaly mask CMOV, MMX, XSAVE if FXSR or FPU is cleared.
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20190703083247.57kjrmlxkai3vpw3@linutronix.de
2019-07-03 08:32:47 +00:00
|
|
|
{ X86_FEATURE_XSAVE, X86_FEATURE_FXSR },
|
2017-10-13 21:56:42 +00:00
|
|
|
{ X86_FEATURE_XMM, X86_FEATURE_FXSR },
|
|
|
|
{ X86_FEATURE_XMM2, X86_FEATURE_XMM },
|
|
|
|
{ X86_FEATURE_XMM3, X86_FEATURE_XMM2 },
|
|
|
|
{ X86_FEATURE_XMM4_1, X86_FEATURE_XMM2 },
|
|
|
|
{ X86_FEATURE_XMM4_2, X86_FEATURE_XMM2 },
|
|
|
|
{ X86_FEATURE_XMM3, X86_FEATURE_XMM2 },
|
|
|
|
{ X86_FEATURE_PCLMULQDQ, X86_FEATURE_XMM2 },
|
|
|
|
{ X86_FEATURE_SSSE3, X86_FEATURE_XMM2, },
|
|
|
|
{ X86_FEATURE_F16C, X86_FEATURE_XMM2, },
|
|
|
|
{ X86_FEATURE_AES, X86_FEATURE_XMM2 },
|
|
|
|
{ X86_FEATURE_SHA_NI, X86_FEATURE_XMM2 },
|
|
|
|
{ X86_FEATURE_FMA, X86_FEATURE_AVX },
|
|
|
|
{ X86_FEATURE_AVX2, X86_FEATURE_AVX, },
|
|
|
|
{ X86_FEATURE_AVX512F, X86_FEATURE_AVX, },
|
|
|
|
{ X86_FEATURE_AVX512IFMA, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512PF, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512ER, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512CD, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512DQ, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512BW, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512VL, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512VBMI, X86_FEATURE_AVX512F },
|
x86/cpufeatures: Enable new SSE/AVX/AVX512 CPU features
Add a few new SSE/AVX/AVX512 instruction groups/features for enumeration
in /proc/cpuinfo: AVX512_VBMI2, GFNI, VAES, VPCLMULQDQ, AVX512_VNNI,
AVX512_BITALG.
CPUID.(EAX=7,ECX=0):ECX[bit 6] AVX512_VBMI2
CPUID.(EAX=7,ECX=0):ECX[bit 8] GFNI
CPUID.(EAX=7,ECX=0):ECX[bit 9] VAES
CPUID.(EAX=7,ECX=0):ECX[bit 10] VPCLMULQDQ
CPUID.(EAX=7,ECX=0):ECX[bit 11] AVX512_VNNI
CPUID.(EAX=7,ECX=0):ECX[bit 12] AVX512_BITALG
Detailed information of CPUID bits for these features can be found
in the Intel Architecture Instruction Set Extensions and Future Features
Programming Interface document (refer to Table 1-1. and Table 1-2.).
A copy of this document is available at
https://bugzilla.kernel.org/show_bug.cgi?id=197239
Signed-off-by: Gayatri Kammela <gayatri.kammela@intel.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andi Kleen <andi.kleen@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Shankar <ravi.v.shankar@intel.com>
Cc: Ricardo Neri <ricardo.neri@intel.com>
Cc: Yang Zhong <yang.zhong@intel.com>
Cc: bp@alien8.de
Link: http://lkml.kernel.org/r/1509412829-23380-1-git-send-email-gayatri.kammela@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2017-10-31 01:20:29 +00:00
|
|
|
{ X86_FEATURE_AVX512_VBMI2, X86_FEATURE_AVX512VL },
|
|
|
|
{ X86_FEATURE_GFNI, X86_FEATURE_AVX512VL },
|
|
|
|
{ X86_FEATURE_VAES, X86_FEATURE_AVX512VL },
|
|
|
|
{ X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX512VL },
|
|
|
|
{ X86_FEATURE_AVX512_VNNI, X86_FEATURE_AVX512VL },
|
|
|
|
{ X86_FEATURE_AVX512_BITALG, X86_FEATURE_AVX512VL },
|
2017-10-13 21:56:42 +00:00
|
|
|
{ X86_FEATURE_AVX512_4VNNIW, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512_4FMAPS, X86_FEATURE_AVX512F },
|
|
|
|
{ X86_FEATURE_AVX512_VPOPCNTDQ, X86_FEATURE_AVX512F },
|
2019-06-19 16:51:09 +00:00
|
|
|
{ X86_FEATURE_CQM_OCCUP_LLC, X86_FEATURE_CQM_LLC },
|
|
|
|
{ X86_FEATURE_CQM_MBM_TOTAL, X86_FEATURE_CQM_LLC },
|
|
|
|
{ X86_FEATURE_CQM_MBM_LOCAL, X86_FEATURE_CQM_LLC },
|
2019-06-17 18:00:16 +00:00
|
|
|
{ X86_FEATURE_AVX512_BF16, X86_FEATURE_AVX512VL },
|
2017-10-13 21:56:42 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline void clear_feature(struct cpuinfo_x86 *c, unsigned int feature)
|
|
|
|
{
|
2017-11-02 12:22:35 +00:00
|
|
|
/*
|
|
|
|
* Note: This could use the non atomic __*_bit() variants, but the
|
|
|
|
* rest of the cpufeature code uses atomics as well, so keep it for
|
|
|
|
* consistency. Cleanup all of it separately.
|
|
|
|
*/
|
|
|
|
if (!c) {
|
|
|
|
clear_cpu_cap(&boot_cpu_data, feature);
|
|
|
|
set_bit(feature, (unsigned long *)cpu_caps_cleared);
|
|
|
|
} else {
|
|
|
|
clear_bit(feature, (unsigned long *)c->x86_capability);
|
|
|
|
}
|
2017-10-13 21:56:42 +00:00
|
|
|
}
|
|
|
|
|
2017-10-18 17:39:35 +00:00
|
|
|
/* Take the capabilities and the BUG bits into account */
|
|
|
|
#define MAX_FEATURE_BITS ((NCAPINTS + NBUGINTS) * sizeof(u32) * 8)
|
|
|
|
|
2017-10-13 21:56:42 +00:00
|
|
|
static void do_clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
|
|
|
|
{
|
2017-10-18 17:39:35 +00:00
|
|
|
DECLARE_BITMAP(disable, MAX_FEATURE_BITS);
|
2017-10-13 21:56:42 +00:00
|
|
|
const struct cpuid_dep *d;
|
2017-10-18 17:39:35 +00:00
|
|
|
bool changed;
|
|
|
|
|
|
|
|
if (WARN_ON(feature >= MAX_FEATURE_BITS))
|
|
|
|
return;
|
2017-10-13 21:56:42 +00:00
|
|
|
|
|
|
|
clear_feature(c, feature);
|
|
|
|
|
|
|
|
/* Collect all features to disable, handling dependencies */
|
|
|
|
memset(disable, 0, sizeof(disable));
|
|
|
|
__set_bit(feature, disable);
|
|
|
|
|
|
|
|
/* Loop until we get a stable state. */
|
|
|
|
do {
|
|
|
|
changed = false;
|
|
|
|
for (d = cpuid_deps; d->feature; d++) {
|
|
|
|
if (!test_bit(d->depends, disable))
|
|
|
|
continue;
|
|
|
|
if (__test_and_set_bit(d->feature, disable))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
changed = true;
|
|
|
|
clear_feature(c, d->feature);
|
|
|
|
}
|
|
|
|
} while (changed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
|
|
|
|
{
|
|
|
|
do_clear_cpu_cap(c, feature);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setup_clear_cpu_cap(unsigned int feature)
|
|
|
|
{
|
|
|
|
do_clear_cpu_cap(NULL, feature);
|
|
|
|
}
|