提交 89388913 编写于 作者: P Pekka Enberg 提交者: Ingo Molnar

x86: unify noexec handling

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

[ Impact: cleanup ]
Signed-off-by: NPekka Enberg <penberg@cs.helsinki.fi>
[ mingo@elte.hu: build fix ]
LKML-Reference: <1240303167.771.69.camel@penberg-laptop>
Signed-off-by: NIngo Molnar <mingo@elte.hu>
上级 8ecee462
...@@ -273,7 +273,6 @@ typedef struct page *pgtable_t; ...@@ -273,7 +273,6 @@ typedef struct page *pgtable_t;
extern pteval_t __supported_pte_mask; extern pteval_t __supported_pte_mask;
extern int nx_enabled; extern int nx_enabled;
extern void set_nx(void);
#define pgprot_writecombine pgprot_writecombine #define pgprot_writecombine pgprot_writecombine
extern pgprot_t pgprot_writecombine(pgprot_t prot); extern pgprot_t pgprot_writecombine(pgprot_t prot);
......
...@@ -22,6 +22,69 @@ int direct_gbpages ...@@ -22,6 +22,69 @@ int direct_gbpages
#endif #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, static void __init find_early_table_space(unsigned long end, int use_pse,
int use_gbpages) int use_gbpages)
{ {
...@@ -158,12 +221,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, ...@@ -158,12 +221,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
use_gbpages = direct_gbpages; use_gbpages = direct_gbpages;
#endif #endif
#ifdef CONFIG_X86_32
#ifdef CONFIG_X86_PAE
set_nx(); set_nx();
if (nx_enabled) if (nx_enabled)
printk(KERN_INFO "NX (Execute Disable) protection: active\n"); printk(KERN_INFO "NX (Execute Disable) protection: active\n");
#endif
/* Enable PSE if available */ /* Enable PSE if available */
if (cpu_has_pse) if (cpu_has_pse)
...@@ -174,7 +234,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, ...@@ -174,7 +234,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
set_in_cr4(X86_CR4_PGE); set_in_cr4(X86_CR4_PGE);
__supported_pte_mask |= _PAGE_GLOBAL; __supported_pte_mask |= _PAGE_GLOBAL;
} }
#endif
if (use_gbpages) if (use_gbpages)
page_size_mask |= 1 << PG_LEVEL_1G; page_size_mask |= 1 << PG_LEVEL_1G;
......
...@@ -587,61 +587,9 @@ void zap_low_mappings(void) ...@@ -587,61 +587,9 @@ void zap_low_mappings(void)
flush_tlb_all(); flush_tlb_all();
} }
int nx_enabled;
pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP); pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
EXPORT_SYMBOL_GPL(__supported_pte_mask); 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 */ /* user-defined highmem size */
static unsigned int highmem_pages = -1; static unsigned int highmem_pages = -1;
......
...@@ -85,39 +85,6 @@ early_param("gbpages", parse_direct_gbpages_on); ...@@ -85,39 +85,6 @@ early_param("gbpages", parse_direct_gbpages_on);
pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP; pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
EXPORT_SYMBOL_GPL(__supported_pte_mask); 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; int force_personality32;
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册