1c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge#include <linux/spinlock.h>
2c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge#include <linux/errno.h>
3c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge#include <linux/init.h>
4c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge
5c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge#include <asm/pgtable.h>
64763ed4d45522b876c97e1f7f4b659d211f75571H. Peter Anvin#include <asm/proto.h>
7c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge
8148f9bb87745ed45f7a11b2cbd3bc0f017d5d257Paul Gortmakerstatic int disable_nx;
9c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge
10c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge/*
11c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge * noexec = on|off
12c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge *
13c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge * Control non-executable mappings for processes.
14c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge *
15c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge * on      Enable
16c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge * off     Disable
17c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge */
18c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardingestatic int __init noexec_setup(char *str)
19c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge{
20c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge	if (!str)
21c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge		return -EINVAL;
22c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge	if (!strncmp(str, "on", 2)) {
23c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge		disable_nx = 0;
24c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge	} else if (!strncmp(str, "off", 3)) {
25c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge		disable_nx = 1;
26c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge	}
274763ed4d45522b876c97e1f7f4b659d211f75571H. Peter Anvin	x86_configure_nx();
28c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge	return 0;
29c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge}
30c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardingeearly_param("noexec", noexec_setup);
31c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge
32148f9bb87745ed45f7a11b2cbd3bc0f017d5d257Paul Gortmakervoid x86_configure_nx(void)
33c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge{
344763ed4d45522b876c97e1f7f4b659d211f75571H. Peter Anvin	if (cpu_has_nx && !disable_nx)
354763ed4d45522b876c97e1f7f4b659d211f75571H. Peter Anvin		__supported_pte_mask |= _PAGE_NX;
364763ed4d45522b876c97e1f7f4b659d211f75571H. Peter Anvin	else
37c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge		__supported_pte_mask &= ~_PAGE_NX;
38c44c9ec0f38b939b3200436e3aa95c1aa83c41c7Jeremy Fitzhardinge}
394b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook
404b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cookvoid __init x86_report_nx(void)
414b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook{
424b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook	if (!cpu_has_nx) {
434b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook		printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
446036f373ea03687d355634fa70fb04baa95ab75eKees Cook		       "missing in CPU!\n");
454b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook	} else {
464b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
474b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook		if (disable_nx) {
484b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook			printk(KERN_INFO "NX (Execute Disable) protection: "
494b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook			       "disabled by kernel command line option\n");
504b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook		} else {
514b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook			printk(KERN_INFO "NX (Execute Disable) protection: "
524b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook			       "active\n");
534b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook		}
544b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook#else
554b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook		/* 32bit non-PAE kernel, NX cannot be used */
564b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook		printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
574b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook		       "cannot be enabled: non-PAE kernel!\n");
584b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook#endif
594b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook	}
604b0f3b81eb33ef18283aa71440cccfede1753ae0Kees Cook}
61