Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89388913 authored by Pekka Enberg's avatar Pekka Enberg Committed by Ingo Molnar
Browse files

x86: unify noexec handling



This patch unifies noexec handling on 32-bit and 64-bit.

[ Impact: cleanup ]

Signed-off-by: default avatarPekka Enberg <penberg@cs.helsinki.fi>
[ mingo@elte.hu: build fix ]
LKML-Reference: <1240303167.771.69.camel@penberg-laptop>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 8ecee462
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -273,7 +273,6 @@ typedef struct page *pgtable_t;

extern pteval_t __supported_pte_mask;
extern int nx_enabled;
extern void set_nx(void);

#define pgprot_writecombine	pgprot_writecombine
extern pgprot_t pgprot_writecombine(pgprot_t prot);
+63 −4
Original line number Diff line number Diff line
@@ -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;
+0 −52
Original line number Diff line number Diff line
@@ -587,61 +587,9 @@ void zap_low_mappings(void)
	flush_tlb_all();
}

int nx_enabled;

pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
EXPORT_SYMBOL_GPL(__supported_pte_mask);

#ifdef CONFIG_X86_PAE

static int disable_nx __initdata;

/*
 * noexec = on|off
 *
 * Control non executable mappings.
 *
 * on      Enable
 * off     Disable
 */
static int __init noexec_setup(char *str)
{
	if (!str || !strcmp(str, "on")) {
		if (cpu_has_nx) {
			__supported_pte_mask |= _PAGE_NX;
			disable_nx = 0;
		}
	} else {
		if (!strcmp(str, "off")) {
			disable_nx = 1;
			__supported_pte_mask &= ~_PAGE_NX;
		} else {
			return -EINVAL;
		}
	}

	return 0;
}
early_param("noexec", noexec_setup);

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;
		}
	}
}
#endif

/* user-defined highmem size */
static unsigned int highmem_pages = -1;

+0 −33
Original line number Diff line number Diff line
@@ -85,39 +85,6 @@ early_param("gbpages", parse_direct_gbpages_on);
pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
EXPORT_SYMBOL_GPL(__supported_pte_mask);

static int disable_nx __cpuinitdata;

/*
 * noexec=on|off
 * Control non-executable mappings for 64-bit processes.
 *
 * on	Enable (default)
 * off	Disable
 */
static int __init nonx_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", nonx_setup);

void __cpuinit check_efer(void)
{
	unsigned long efer;

	rdmsrl(MSR_EFER, efer);
	if (!(efer & EFER_NX) || disable_nx)
		__supported_pte_mask &= ~_PAGE_NX;
}

int force_personality32;

/*