]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
x86/fpu: Allow multiple bits in clearcpuid= parameter
authorArvind Sankar <nivedita@alum.mit.edu>
Mon, 7 Sep 2020 21:39:19 +0000 (17:39 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 09:07:14 +0000 (10:07 +0100)
[ Upstream commit 0a4bb5e5507a585532cc413125b921c8546fc39f ]

Commit

  0c2a3913d6f5 ("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: 0c2a3913d6f5 ("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>
Documentation/admin-guide/kernel-parameters.txt
arch/x86/kernel/fpu/init.c

index fb95fad81c79a065e728202a34a3dabac5653cb4..6746f91ebc49083e69b53266003b9a3fc01408f8 100644 (file)
                        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
index 61ddc3a5e5c2b659296b7720350d058e6ea009fc..f8ff895aaf7e17b8559a3c793453cf06b64d12b1 100644 (file)
@@ -243,9 +243,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;
 
 #ifdef CONFIG_X86_32
        if (cmdline_find_option_bool(boot_command_line, "no387"))
@@ -268,12 +268,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)
-               setup_clear_cpu_cap(bit);
+       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");
 }
 
 /*