x86/fpu: Allow multiple bits in clearcpuid= parameter
[ Upstream commit 0a4bb5e5507a585532cc413125b921c8546fc39f ] Commit0c2a3913d6
("x86/fpu: Parse clearcpuid= as early XSAVE argument") changed clearcpuid parsing from __setup() to cmdline_find_option(). While the __setup() function would have been called for each clearcpuid= parameter on the command line, cmdline_find_option() will only return the last one, so the change effectively made it impossible to disable more than one bit. Allow a comma-separated list of bit numbers as the argument for clearcpuid to allow multiple bits to be disabled again. Log the bits being disabled for informational purposes. Also fix the check on the return value of cmdline_find_option(). It returns -1 when the option is not found, so testing as a boolean is incorrect. Fixes:0c2a3913d6
("x86/fpu: Parse clearcpuid= as early XSAVE argument") Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20200907213919.2423441-1-nivedita@alum.mit.edu Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
dc0e1c9184
commit
87ab5f1415
2 changed files with 23 additions and 9 deletions
|
@ -558,7 +558,7 @@
|
|||
loops can be debugged more effectively on production
|
||||
systems.
|
||||
|
||||
clearcpuid=BITNUM [X86]
|
||||
clearcpuid=BITNUM[,BITNUM...] [X86]
|
||||
Disable CPUID feature X for the kernel. See
|
||||
arch/x86/include/asm/cpufeatures.h for the valid bit
|
||||
numbers. Note the Linux specific bits are not necessarily
|
||||
|
|
|
@ -249,9 +249,9 @@ static void __init fpu__init_system_ctx_switch(void)
|
|||
*/
|
||||
static void __init fpu__init_parse_early_param(void)
|
||||
{
|
||||
char arg[32];
|
||||
char arg[128];
|
||||
char *argptr = arg;
|
||||
int bit;
|
||||
int arglen, res, bit;
|
||||
|
||||
if (cmdline_find_option_bool(boot_command_line, "no387"))
|
||||
setup_clear_cpu_cap(X86_FEATURE_FPU);
|
||||
|
@ -271,12 +271,26 @@ static void __init fpu__init_parse_early_param(void)
|
|||
if (cmdline_find_option_bool(boot_command_line, "noxsaves"))
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVES);
|
||||
|
||||
if (cmdline_find_option(boot_command_line, "clearcpuid", arg,
|
||||
sizeof(arg)) &&
|
||||
get_option(&argptr, &bit) &&
|
||||
bit >= 0 &&
|
||||
bit < NCAPINTS * 32)
|
||||
arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg));
|
||||
if (arglen <= 0)
|
||||
return;
|
||||
|
||||
pr_info("Clearing CPUID bits:");
|
||||
do {
|
||||
res = get_option(&argptr, &bit);
|
||||
if (res == 0 || res == 3)
|
||||
break;
|
||||
|
||||
/* If the argument was too long, the last bit may be cut off */
|
||||
if (res == 1 && arglen >= sizeof(arg))
|
||||
break;
|
||||
|
||||
if (bit >= 0 && bit < NCAPINTS * 32) {
|
||||
pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit));
|
||||
setup_clear_cpu_cap(bit);
|
||||
}
|
||||
} while (res == 2);
|
||||
pr_cont("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue