x86/pti: Fix kernel warnings for pti= and nopti cmdline options
authorJo Van Bulck <jo.vanbulck@cs.kuleuven.be>
Sat, 19 Aug 2023 08:09:21 +0000 (10:09 +0200)
committerBorislav Petkov (AMD) <bp@alien8.de>
Fri, 20 Oct 2023 10:50:14 +0000 (12:50 +0200)
Parse the pti= and nopti cmdline options using early_param to fix 'Unknown
kernel command line parameters "nopti", will be passed to user space'
warnings in the kernel log when nopti or pti= are passed to the kernel
cmdline on x86 platforms.

Additionally allow the kernel to warn for malformed pti= options.

Signed-off-by: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
Link: https://lore.kernel.org/r/20230819080921.5324-2-jo.vanbulck@cs.kuleuven.be
arch/x86/mm/pti.c

index 78414c6d1b5ed1c245d13767907649b40f88b993..5dd733944629fa1f7ac38a19281a9c04fa173ccb 100644 (file)
@@ -69,6 +69,7 @@ static void __init pti_print_if_secure(const char *reason)
                pr_info("%s\n", reason);
 }
 
+/* Assume mode is auto unless overridden via cmdline below. */
 static enum pti_mode {
        PTI_AUTO = 0,
        PTI_FORCE_OFF,
@@ -77,50 +78,49 @@ static enum pti_mode {
 
 void __init pti_check_boottime_disable(void)
 {
-       char arg[5];
-       int ret;
-
-       /* Assume mode is auto unless overridden. */
-       pti_mode = PTI_AUTO;
-
        if (hypervisor_is_type(X86_HYPER_XEN_PV)) {
                pti_mode = PTI_FORCE_OFF;
                pti_print_if_insecure("disabled on XEN PV.");
                return;
        }
 
-       ret = cmdline_find_option(boot_command_line, "pti", arg, sizeof(arg));
-       if (ret > 0)  {
-               if (ret == 3 && !strncmp(arg, "off", 3)) {
-                       pti_mode = PTI_FORCE_OFF;
-                       pti_print_if_insecure("disabled on command line.");
-                       return;
-               }
-               if (ret == 2 && !strncmp(arg, "on", 2)) {
-                       pti_mode = PTI_FORCE_ON;
-                       pti_print_if_secure("force enabled on command line.");
-                       goto enable;
-               }
-               if (ret == 4 && !strncmp(arg, "auto", 4)) {
-                       pti_mode = PTI_AUTO;
-                       goto autosel;
-               }
-       }
-
-       if (cmdline_find_option_bool(boot_command_line, "nopti") ||
-           cpu_mitigations_off()) {
+       if (cpu_mitigations_off())
                pti_mode = PTI_FORCE_OFF;
+       if (pti_mode == PTI_FORCE_OFF) {
                pti_print_if_insecure("disabled on command line.");
                return;
        }
 
-autosel:
-       if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN))
+       if (pti_mode == PTI_FORCE_ON)
+               pti_print_if_secure("force enabled on command line.");
+
+       if (pti_mode == PTI_AUTO && !boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN))
                return;
-enable:
+
        setup_force_cpu_cap(X86_FEATURE_PTI);
 }
 
+static int __init pti_parse_cmdline(char *arg)
+{
+       if (!strcmp(arg, "off"))
+               pti_mode = PTI_FORCE_OFF;
+       else if (!strcmp(arg, "on"))
+               pti_mode = PTI_FORCE_ON;
+       else if (!strcmp(arg, "auto"))
+               pti_mode = PTI_AUTO;
+       else
+               return -EINVAL;
+       return 0;
+}
+early_param("pti", pti_parse_cmdline);
+
+static int __init pti_parse_cmdline_nopti(char *arg)
+{
+       pti_mode = PTI_FORCE_OFF;
+       return 0;
+}
+early_param("nopti", pti_parse_cmdline_nopti);
+
 pgd_t __pti_set_user_pgtbl(pgd_t *pgdp, pgd_t pgd)
 {
        /*