aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-09-26 04:52:37 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:37 -0400
commitdf992848f5aa803fcacd2c5e7d67034bb89e3fa3 (patch)
tree649ee5888f71bdd4243599f73d9725118262d368
parentd3cf7f061521c78ad62e275eb6fbdc8f43fc75a7 (diff)
[PATCH] Fix pte_exec/mkexec and use it in change_page_attr()
Fix the pte_exec/mkexec page table accessor functions to really use the NX bit. Previously they only checked the USER bit, but weren't actually used for anything. Then use them in change_page_attr() to manipulate the NX bit properly. Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r--arch/x86_64/mm/pageattr.c8
-rw-r--r--include/asm-x86_64/pgtable.h4
2 files changed, 7 insertions, 5 deletions
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 2685b1f3671c..01591b649f4e 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -190,10 +190,12 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
190 * lowmem */ 190 * lowmem */
191 if (__pa(address) < KERNEL_TEXT_SIZE) { 191 if (__pa(address) < KERNEL_TEXT_SIZE) {
192 unsigned long addr2; 192 unsigned long addr2;
193 pgprot_t prot2 = prot; 193 pgprot_t prot2;
194 addr2 = __START_KERNEL_map + __pa(address); 194 addr2 = __START_KERNEL_map + __pa(address);
195 pgprot_val(prot2) &= ~_PAGE_NX; 195 /* Make sure the kernel mappings stay executable */
196 err = __change_page_attr(addr2, pfn, prot2, PAGE_KERNEL_EXEC); 196 prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
197 err = __change_page_attr(addr2, pfn, prot2,
198 PAGE_KERNEL_EXEC);
197 } 199 }
198 } 200 }
199 up_write(&init_mm.mmap_sem); 201 up_write(&init_mm.mmap_sem);
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index d79e7441b513..f7614670c655 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -265,7 +265,7 @@ static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
265#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) 265#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
266static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; } 266static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
267static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } 267static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
268static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } 268static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); }
269static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } 269static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
270static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } 270static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
271static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } 271static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
@@ -278,7 +278,7 @@ static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) &
278static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; } 278static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
279static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; } 279static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
280static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } 280static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
281static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } 281static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; }
282static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } 282static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
283static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } 283static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
284static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } 284static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }