Skip to content

Commit b45c14f

Browse files
nivedita76gregkh
authored andcommitted
x86/fpu: Allow multiple bits in clearcpuid= parameter
[ Upstream commit 0a4bb5e ] Commit 0c2a391 ("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: 0c2a391 ("x86/fpu: Parse clearcpuid= as early XSAVE argument") Signed-off-by: Arvind Sankar <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Sasha Levin <[email protected]>
1 parent 4f596c7 commit b45c14f

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@
577577
loops can be debugged more effectively on production
578578
systems.
579579

580-
clearcpuid=BITNUM [X86]
580+
clearcpuid=BITNUM[,BITNUM...] [X86]
581581
Disable CPUID feature X for the kernel. See
582582
arch/x86/include/asm/cpufeatures.h for the valid bit
583583
numbers. Note the Linux specific bits are not necessarily

arch/x86/kernel/fpu/init.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,9 @@ static void __init fpu__init_system_ctx_switch(void)
243243
*/
244244
static void __init fpu__init_parse_early_param(void)
245245
{
246-
char arg[32];
246+
char arg[128];
247247
char *argptr = arg;
248-
int bit;
248+
int arglen, res, bit;
249249

250250
#ifdef CONFIG_X86_32
251251
if (cmdline_find_option_bool(boot_command_line, "no387"))
@@ -268,12 +268,26 @@ static void __init fpu__init_parse_early_param(void)
268268
if (cmdline_find_option_bool(boot_command_line, "noxsaves"))
269269
setup_clear_cpu_cap(X86_FEATURE_XSAVES);
270270

271-
if (cmdline_find_option(boot_command_line, "clearcpuid", arg,
272-
sizeof(arg)) &&
273-
get_option(&argptr, &bit) &&
274-
bit >= 0 &&
275-
bit < NCAPINTS * 32)
276-
setup_clear_cpu_cap(bit);
271+
arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg));
272+
if (arglen <= 0)
273+
return;
274+
275+
pr_info("Clearing CPUID bits:");
276+
do {
277+
res = get_option(&argptr, &bit);
278+
if (res == 0 || res == 3)
279+
break;
280+
281+
/* If the argument was too long, the last bit may be cut off */
282+
if (res == 1 && arglen >= sizeof(arg))
283+
break;
284+
285+
if (bit >= 0 && bit < NCAPINTS * 32) {
286+
pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit));
287+
setup_clear_cpu_cap(bit);
288+
}
289+
} while (res == 2);
290+
pr_cont("\n");
277291
}
278292

279293
/*

0 commit comments

Comments
 (0)