|
@@ -22,6 +22,69 @@ int direct_gbpages
|
|
|
#endif
|
|
|
;
|
|
|
|
|
|
+int nx_enabled;
|
|
|
+
|
|
|
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
|
|
+static int disable_nx __cpuinitdata;
|
|
|
+
|
|
|
+/*
|
|
|
+ * noexec = on|off
|
|
|
+ *
|
|
|
+ * Control non-executable mappings for processes.
|
|
|
+ *
|
|
|
+ * on Enable
|
|
|
+ * off Disable
|
|
|
+ */
|
|
|
+static int __init noexec_setup(char *str)
|
|
|
+{
|
|
|
+ if (!str)
|
|
|
+ return -EINVAL;
|
|
|
+ if (!strncmp(str, "on", 2)) {
|
|
|
+ __supported_pte_mask |= _PAGE_NX;
|
|
|
+ disable_nx = 0;
|
|
|
+ } else if (!strncmp(str, "off", 3)) {
|
|
|
+ disable_nx = 1;
|
|
|
+ __supported_pte_mask &= ~_PAGE_NX;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+early_param("noexec", noexec_setup);
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef CONFIG_X86_PAE
|
|
|
+static void __init set_nx(void)
|
|
|
+{
|
|
|
+ unsigned int v[4], l, h;
|
|
|
+
|
|
|
+ if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
|
|
|
+ cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
|
|
|
+
|
|
|
+ if ((v[3] & (1 << 20)) && !disable_nx) {
|
|
|
+ rdmsr(MSR_EFER, l, h);
|
|
|
+ l |= EFER_NX;
|
|
|
+ wrmsr(MSR_EFER, l, h);
|
|
|
+ nx_enabled = 1;
|
|
|
+ __supported_pte_mask |= _PAGE_NX;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline void set_nx(void)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
+void __cpuinit check_efer(void)
|
|
|
+{
|
|
|
+ unsigned long efer;
|
|
|
+
|
|
|
+ rdmsrl(MSR_EFER, efer);
|
|
|
+ if (!(efer & EFER_NX) || disable_nx)
|
|
|
+ __supported_pte_mask &= ~_PAGE_NX;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static void __init find_early_table_space(unsigned long end, int use_pse,
|
|
|
int use_gbpages)
|
|
|
{
|
|
@@ -158,12 +221,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
|
|
|
use_gbpages = direct_gbpages;
|
|
|
#endif
|
|
|
|
|
|
-#ifdef CONFIG_X86_32
|
|
|
-#ifdef CONFIG_X86_PAE
|
|
|
set_nx();
|
|
|
if (nx_enabled)
|
|
|
printk(KERN_INFO "NX (Execute Disable) protection: active\n");
|
|
|
-#endif
|
|
|
|
|
|
/* Enable PSE if available */
|
|
|
if (cpu_has_pse)
|
|
@@ -174,7 +234,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
|
|
|
set_in_cr4(X86_CR4_PGE);
|
|
|
__supported_pte_mask |= _PAGE_GLOBAL;
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
if (use_gbpages)
|
|
|
page_size_mask |= 1 << PG_LEVEL_1G;
|