x86, mm: Report state of NX protections during boot
authorKees Cook <kees.cook@canonical.com>
Fri, 13 Nov 2009 23:28:17 +0000 (15:28 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 16 Nov 2009 21:44:59 +0000 (13:44 -0800)
It is possible for x86_64 systems to lack the NX bit either due to the
hardware lacking support or the BIOS having turned off the CPU capability,
so NX status should be reported.  Additionally, anyone booting NX-capable
CPUs in 32bit mode without PAE will lack NX functionality, so this change
provides feedback for that case as well.

Signed-off-by: Kees Cook <kees.cook@canonical.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
LKML-Reference: <1258154897-6770-6-git-send-email-hpa@zytor.com>

arch/x86/include/asm/proto.h
arch/x86/kernel/setup.c
arch/x86/mm/init.c
arch/x86/mm/setup_nx.c

index add7f18f17a754fc12c5493af3f7586aa1b125a0..450c56bcd4f8eb8507e8980425c1c9d54547733e 100644 (file)
@@ -17,6 +17,7 @@ extern void ia32_sysenter_target(void);
 extern void syscall32_cpu_init(void);
 
 extern void x86_configure_nx(void);
+extern void x86_report_nx(void);
 
 extern int reboot_force;
 
index 23b7f46bf8434567b32234ddacd9f515830128ed..d2043a00abc1817a11bed959ba7473189652efcf 100644 (file)
@@ -788,16 +788,17 @@ void __init setup_arch(char **cmdline_p)
        *cmdline_p = command_line;
 
        /*
-        * Must call this twice: Once just to detect whether hardware doesn't
-        * support NX (so that the early EHCI debug console setup can safely
-        * call set_fixmap(), and then again after parsing early parameters to
-        * honor the respective command line option.
+        * x86_configure_nx() is called before parse_early_param() to detect
+        * whether hardware doesn't support NX (so that the early EHCI debug
+        * console setup can safely call set_fixmap()). It may then be called
+        * again from within noexec_setup() during parsing early parameters
+        * to honor the respective command line option.
         */
        x86_configure_nx();
 
        parse_early_param();
 
-       x86_configure_nx();
+       x86_report_nx();
 
        /* Must be before kernel pagetables are setup */
        vmi_activate();
index 27ec2c23fd474cf74ed3b61619098744f90df286..d406c5239019ee0e2e9609c826f1a2ba8564c693 100644 (file)
@@ -146,10 +146,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
        use_gbpages = direct_gbpages;
 #endif
 
-       /* XXX: replace this with Kees' improved messages */
-       if (__supported_pte_mask & _PAGE_NX)
-               printk(KERN_INFO "NX (Execute Disable) protection: active\n");
-
        /* Enable PSE if available */
        if (cpu_has_pse)
                set_in_cr4(X86_CR4_PSE);
index 355818b087b52044dfc3494813260911f9f49958..a3250aa34086fce7d376e9e1e464fa2e996dbb6d 100644 (file)
@@ -36,3 +36,25 @@ void __cpuinit x86_configure_nx(void)
        else
                __supported_pte_mask &= ~_PAGE_NX;
 }
+
+void __init x86_report_nx(void)
+{
+       if (!cpu_has_nx) {
+               printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
+                      "missing in CPU or disabled in BIOS!\n");
+       } else {
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+               if (disable_nx) {
+                       printk(KERN_INFO "NX (Execute Disable) protection: "
+                              "disabled by kernel command line option\n");
+               } else {
+                       printk(KERN_INFO "NX (Execute Disable) protection: "
+                              "active\n");
+               }
+#else
+               /* 32bit non-PAE kernel, NX cannot be used */
+               printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
+                      "cannot be enabled: non-PAE kernel!\n");
+#endif
+       }
+}