x86: unify noexec handling
This patch unifies noexec handling on 32-bit and 64-bit. [ Impact: cleanup ] Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi> [ mingo@elte.hu: build fix ] LKML-Reference: <1240303167.771.69.camel@penberg-laptop> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
Ingo Molnar
parent
8ecee4620e
commit
89388913f2
@@ -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
|
|||||||
#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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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);
|
|||||||
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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user