diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/mm/pageattr.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 4589a1382fa1..effcd78d5f40 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -22,6 +22,27 @@ void clflush_cache_range(void *addr, int size) | |||
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <asm/pgalloc.h> | 23 | #include <asm/pgalloc.h> |
24 | 24 | ||
25 | /* | ||
26 | * We allow the BIOS range to be executable: | ||
27 | */ | ||
28 | #define BIOS_BEGIN 0x000a0000 | ||
29 | #define BIOS_END 0x00100000 | ||
30 | |||
31 | static inline pgprot_t check_exec(pgprot_t prot, unsigned long address) | ||
32 | { | ||
33 | if (__pa(address) >= BIOS_BEGIN && __pa(address) < BIOS_END) | ||
34 | pgprot_val(prot) &= ~_PAGE_NX; | ||
35 | /* | ||
36 | * Better fail early if someone sets the kernel text to NX. | ||
37 | * Does not cover __inittext | ||
38 | */ | ||
39 | BUG_ON(address >= (unsigned long)&_text && | ||
40 | address < (unsigned long)&_etext && | ||
41 | (pgprot_val(prot) & _PAGE_NX)); | ||
42 | |||
43 | return prot; | ||
44 | } | ||
45 | |||
25 | pte_t *lookup_address(unsigned long address, int *level) | 46 | pte_t *lookup_address(unsigned long address, int *level) |
26 | { | 47 | { |
27 | pgd_t *pgd = pgd_offset_k(address); | 48 | pgd_t *pgd = pgd_offset_k(address); |
@@ -140,13 +161,7 @@ repeat: | |||
140 | BUG_ON(PageLRU(kpte_page)); | 161 | BUG_ON(PageLRU(kpte_page)); |
141 | BUG_ON(PageCompound(kpte_page)); | 162 | BUG_ON(PageCompound(kpte_page)); |
142 | 163 | ||
143 | /* | 164 | prot = check_exec(prot, address); |
144 | * Better fail early if someone sets the kernel text to NX. | ||
145 | * Does not cover __inittext | ||
146 | */ | ||
147 | BUG_ON(address >= (unsigned long)&_text && | ||
148 | address < (unsigned long)&_etext && | ||
149 | (pgprot_val(prot) & _PAGE_NX)); | ||
150 | 165 | ||
151 | if (level == PG_LEVEL_4K) { | 166 | if (level == PG_LEVEL_4K) { |
152 | set_pte_atomic(kpte, mk_pte(page, canon_pgprot(prot))); | 167 | set_pte_atomic(kpte, mk_pte(page, canon_pgprot(prot))); |