diff options
Diffstat (limited to 'arch/ppc/mm/fault.c')
-rw-r--r-- | arch/ppc/mm/fault.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index 0217188ef465..8e08ca32531a 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c | |||
@@ -202,6 +202,7 @@ good_area: | |||
202 | /* an exec - 4xx/Book-E allows for per-page execute permission */ | 202 | /* an exec - 4xx/Book-E allows for per-page execute permission */ |
203 | } else if (TRAP(regs) == 0x400) { | 203 | } else if (TRAP(regs) == 0x400) { |
204 | pte_t *ptep; | 204 | pte_t *ptep; |
205 | pmd_t *pmdp; | ||
205 | 206 | ||
206 | #if 0 | 207 | #if 0 |
207 | /* It would be nice to actually enforce the VM execute | 208 | /* It would be nice to actually enforce the VM execute |
@@ -215,21 +216,24 @@ good_area: | |||
215 | /* Since 4xx/Book-E supports per-page execute permission, | 216 | /* Since 4xx/Book-E supports per-page execute permission, |
216 | * we lazily flush dcache to icache. */ | 217 | * we lazily flush dcache to icache. */ |
217 | ptep = NULL; | 218 | ptep = NULL; |
218 | if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { | 219 | if (get_pteptr(mm, address, &ptep, &pmdp)) { |
219 | struct page *page = pte_page(*ptep); | 220 | spinlock_t *ptl = pte_lockptr(mm, pmdp); |
220 | 221 | spin_lock(ptl); | |
221 | if (! test_bit(PG_arch_1, &page->flags)) { | 222 | if (pte_present(*ptep)) { |
222 | flush_dcache_icache_page(page); | 223 | struct page *page = pte_page(*ptep); |
223 | set_bit(PG_arch_1, &page->flags); | 224 | |
225 | if (!test_bit(PG_arch_1, &page->flags)) { | ||
226 | flush_dcache_icache_page(page); | ||
227 | set_bit(PG_arch_1, &page->flags); | ||
228 | } | ||
229 | pte_update(ptep, 0, _PAGE_HWEXEC); | ||
230 | _tlbie(address); | ||
231 | pte_unmap_unlock(ptep, ptl); | ||
232 | up_read(&mm->mmap_sem); | ||
233 | return 0; | ||
224 | } | 234 | } |
225 | pte_update(ptep, 0, _PAGE_HWEXEC); | 235 | pte_unmap_unlock(ptep, ptl); |
226 | _tlbie(address); | ||
227 | pte_unmap(ptep); | ||
228 | up_read(&mm->mmap_sem); | ||
229 | return 0; | ||
230 | } | 236 | } |
231 | if (ptep != NULL) | ||
232 | pte_unmap(ptep); | ||
233 | #endif | 237 | #endif |
234 | /* a read */ | 238 | /* a read */ |
235 | } else { | 239 | } else { |