powerpc/mm: Cleanup handling of execute permission
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 18 Aug 2009 19:00:34 +0000 (19:00 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 27 Aug 2009 03:12:51 +0000 (13:12 +1000)
This is an attempt at cleaning up a bit the way we handle execute
permission on powerpc. _PAGE_HWEXEC is gone, _PAGE_EXEC is now only
defined by CPUs that can do something with it, and the myriad of
#ifdef's in the I$/D$ coherency code is reduced to 2 cases that
hopefully should cover everything.

The logic on BookE is a little bit different than what it was though
not by much. Since now, _PAGE_EXEC will be set by the generic code
for executable pages, we need to filter out if they are unclean and
recover it. However, I don't expect the code to be more bloated than
it already was in that area due to that change.

I could boast that this brings proper enforcing of per-page execute
permissions to all BookE and 40x but in fact, we've had that now for
some time as a side effect of my previous rework in that area (and
I didn't even know it :-) We would only enable execute permission if
the page was cache clean and we would only cache clean it if we took
and exec fault. Since we now enforce that the later only work if
VM_EXEC is part of the VMA flags, we de-fact already enforce per-page
execute permissions... Unless I missed something

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
15 files changed:
arch/powerpc/include/asm/pgtable-ppc32.h
arch/powerpc/include/asm/pgtable-ppc64.h
arch/powerpc/include/asm/pte-40x.h
arch/powerpc/include/asm/pte-44x.h
arch/powerpc/include/asm/pte-8xx.h
arch/powerpc/include/asm/pte-book3e.h
arch/powerpc/include/asm/pte-common.h
arch/powerpc/include/asm/pte-fsl-booke.h
arch/powerpc/include/asm/pte-hash32.h
arch/powerpc/kernel/head_44x.S
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/mm/40x_mmu.c
arch/powerpc/mm/pgtable.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/mm/tlb_low_64e.S

index c9ff9d75990eb94eaf55944482dff6b5301d3afe..f2c52e25395680a84001e23f6e6a7d79a4ccf955 100644 (file)
@@ -186,7 +186,7 @@ static inline unsigned long pte_update(pte_t *p,
 #endif /* !PTE_ATOMIC_UPDATES */
 
 #ifdef CONFIG_44x
-       if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+       if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
                icache_44x_need_flush = 1;
 #endif
        return old;
@@ -217,7 +217,7 @@ static inline unsigned long long pte_update(pte_t *p,
 #endif /* !PTE_ATOMIC_UPDATES */
 
 #ifdef CONFIG_44x
-       if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+       if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
                icache_44x_need_flush = 1;
 #endif
        return old;
@@ -267,8 +267,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
 {
        unsigned long bits = pte_val(entry) &
-               (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
-                _PAGE_HWEXEC | _PAGE_EXEC);
+               (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
        pte_update(ptep, 0, bits);
 }
 
index 200ec2dfa034adbc971c2992b5f4153cc6eb36cb..806abe7a3fa58c32523a167f90ad18a0ef5f8aa0 100644 (file)
@@ -313,8 +313,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
 static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
 {
        unsigned long bits = pte_val(entry) &
-               (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
-                _PAGE_EXEC | _PAGE_HWEXEC);
+               (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
 
 #ifdef PTE_ATOMIC_UPDATES
        unsigned long old, tmp;
index 07630faae029c0f956c04868b56cab906f204ed6..6c3e1f4378d49efd93655a8d4d4d781cbd480682 100644 (file)
@@ -46,7 +46,7 @@
 #define        _PAGE_RW        0x040   /* software: Writes permitted */
 #define        _PAGE_DIRTY     0x080   /* software: dirty page */
 #define _PAGE_HWWRITE  0x100   /* hardware: Dirty & RW, set in exception */
-#define _PAGE_HWEXEC   0x200   /* hardware: EX permission */
+#define _PAGE_EXEC     0x200   /* hardware: EX permission */
 #define _PAGE_ACCESSED 0x400   /* software: R: page referenced */
 
 #define _PMD_PRESENT   0x400   /* PMD points to page of PTEs */
index 37e98bcf83e0150753466dd07bd08e24ae4fdc18..4192b9bad90164b41d928685547fa32ddf0aafd0 100644 (file)
@@ -78,7 +78,7 @@
 #define _PAGE_PRESENT  0x00000001              /* S: PTE valid */
 #define _PAGE_RW       0x00000002              /* S: Write permission */
 #define _PAGE_FILE     0x00000004              /* S: nonlinear file mapping */
-#define _PAGE_HWEXEC   0x00000004              /* H: Execute permission */
+#define _PAGE_EXEC     0x00000004              /* H: Execute permission */
 #define _PAGE_ACCESSED 0x00000008              /* S: Page referenced */
 #define _PAGE_DIRTY    0x00000010              /* S: Page dirty */
 #define _PAGE_SPECIAL  0x00000020              /* S: Special page */
index 8c6e31251034d853783152bdb36eaa245a37be36..94e979718dcf34011a1bcfb68c32a705d55cd4e3 100644 (file)
@@ -36,7 +36,6 @@
 /* These five software bits must be masked out when the entry is loaded
  * into the TLB.
  */
-#define _PAGE_EXEC     0x0008  /* software: i-cache coherency required */
 #define _PAGE_GUARDED  0x0010  /* software: guarded access */
 #define _PAGE_DIRTY    0x0020  /* software: page changed */
 #define _PAGE_RW       0x0040  /* software: user write access allowed */
index 1d27c77d7704ef0b2db2426f89964ca14981aecd..9800565aebb84835b6c65dc3903281f0c9d3f634 100644 (file)
 #define _PAGE_WRITETHRU        0x800000 /* W: cache write-through */
 
 /* "Higher level" linux bit combinations */
-#define _PAGE_EXEC     _PAGE_BAP_SX /* Can be executed from potentially */
-#define _PAGE_HWEXEC   _PAGE_BAP_UX /* .. and was cache cleaned */
-#define _PAGE_RW       (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
-#define _PAGE_KERNEL_RW        (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
-#define _PAGE_KERNEL_RO        (_PAGE_BAP_SR)
-#define _PAGE_USER     (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
+#define _PAGE_EXEC             _PAGE_BAP_UX /* .. and was cache cleaned */
+#define _PAGE_RW               (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
+#define _PAGE_KERNEL_RW                (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
+#define _PAGE_KERNEL_RO                (_PAGE_BAP_SR)
+#define _PAGE_KERNEL_RWX       (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
+#define _PAGE_KERNEL_ROX       (_PAGE_BAP_SR | _PAGE_BAP_SX)
+#define _PAGE_USER             (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
 
 #define _PAGE_HASHPTE  0
 #define _PAGE_BUSY     0
index 8bb6464ba619e790deb2a1023fdfa9304cc8b096..c3b65076a2635b1f43de1a7515492a529a6a74df 100644 (file)
@@ -13,9 +13,6 @@
 #ifndef _PAGE_HWWRITE
 #define _PAGE_HWWRITE  0
 #endif
-#ifndef _PAGE_HWEXEC
-#define _PAGE_HWEXEC   0
-#endif
 #ifndef _PAGE_EXEC
 #define _PAGE_EXEC     0
 #endif
 #define PMD_PAGE_SIZE(pmd)     bad_call_to_PMD_PAGE_SIZE()
 #endif
 #ifndef _PAGE_KERNEL_RO
-#define _PAGE_KERNEL_RO        0
+#define _PAGE_KERNEL_RO                0
+#endif
+#ifndef _PAGE_KERNEL_ROX
+#define _PAGE_KERNEL_ROX       (_PAGE_EXEC)
 #endif
 #ifndef _PAGE_KERNEL_RW
-#define _PAGE_KERNEL_RW        (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#define _PAGE_KERNEL_RW                (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#endif
+#ifndef _PAGE_KERNEL_RWX
+#define _PAGE_KERNEL_RWX       (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | _PAGE_EXEC)
 #endif
 #ifndef _PAGE_HPTEFLAGS
 #define _PAGE_HPTEFLAGS _PAGE_HASHPTE
@@ -96,8 +99,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
 #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
                         _PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \
                         _PAGE_USER | _PAGE_ACCESSED | \
-                        _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
-                        _PAGE_EXEC | _PAGE_HWEXEC)
+                        _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
 
 /*
  * We define 2 sets of base prot bits, one for basic pages (ie,
@@ -154,11 +156,9 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
                                 _PAGE_NO_CACHE)
 #define PAGE_KERNEL_NCG        __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
                                 _PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_X  __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_EXEC | \
-                                _PAGE_HWEXEC)
+#define PAGE_KERNEL_X  __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX)
 #define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
-#define PAGE_KERNEL_ROX        __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO | _PAGE_EXEC | \
-                                _PAGE_HWEXEC)
+#define PAGE_KERNEL_ROX        __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX)
 
 /* Protection used for kernel text. We want the debuggers to be able to
  * set breakpoints anywhere, so don't write protect the kernel text
index 10820f58acf572355b973a62e5b9d1cb8a1886a5..ce8a9e94ce7f854739c34e5e1a36a060cdb99912 100644 (file)
@@ -23,7 +23,7 @@
 #define _PAGE_FILE     0x00002 /* S: when !present: nonlinear file mapping */
 #define _PAGE_RW       0x00004 /* S: Write permission (SW) */
 #define _PAGE_DIRTY    0x00008 /* S: Page dirty */
-#define _PAGE_HWEXEC   0x00010 /* H: SX permission */
+#define _PAGE_EXEC     0x00010 /* H: SX permission */
 #define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
 
 #define _PAGE_ENDIAN   0x00040 /* H: E bit */
index 16e571c7f9efef1d00e6727e9c5ea7da1c1423f4..4aad4132d0a87fa3e677ebe00b05d0d317fe7292 100644 (file)
@@ -26,7 +26,6 @@
 #define _PAGE_WRITETHRU        0x040   /* W: cache write-through */
 #define _PAGE_DIRTY    0x080   /* C: page changed */
 #define _PAGE_ACCESSED 0x100   /* R: page referenced */
-#define _PAGE_EXEC     0x200   /* software: i-cache coherency required */
 #define _PAGE_RW       0x400   /* software: user write access allowed */
 #define _PAGE_SPECIAL  0x800   /* software: Special page */
 
index 656cfb2d66666f7a140f8e8994bd5dd290c7b3cd..711368b993f2caabafdc972a299739ab13588933 100644 (file)
@@ -497,7 +497,7 @@ tlb_44x_patch_hwater_D:
        mtspr   SPRN_MMUCR,r12
 
        /* Make up the required permissions */
-       li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+       li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
 
        /* Compute pgdir/pmd offset */
        rlwinm  r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29
index eca80482ae72242c543ec01dfbce99455e32cb0b..2c5af52564794bd2b27f3e5e6a8f570bcd464ce0 100644 (file)
@@ -643,7 +643,7 @@ interrupt_base:
 
 4:
        /* Make up the required permissions */
-       li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+       li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
 
        FIND_PTE
        andc.   r13,r13,r11             /* Check permission */
@@ -742,7 +742,7 @@ finish_tlb_load:
 #endif
        mtspr   SPRN_MAS2, r12
 
-       li      r10, (_PAGE_HWEXEC | _PAGE_PRESENT)
+       li      r10, (_PAGE_EXEC | _PAGE_PRESENT)
        rlwimi  r10, r11, 31, 29, 29    /* extract _PAGE_DIRTY into SW */
        and     r12, r11, r10
        andi.   r10, r11, _PAGE_USER    /* Test for _PAGE_USER */
index 29954dc28942ff8408c940402f9cac7a72b7ebd3..f5e7b9ce63ddaa46f9ee10da0636b6d070b95431 100644 (file)
@@ -105,7 +105,7 @@ unsigned long __init mmu_mapin_ram(void)
 
        while (s >= LARGE_PAGE_SIZE_16M) {
                pmd_t *pmdp;
-               unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+               unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_HWWRITE;
 
                pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
                pmd_val(*pmdp++) = val;
@@ -120,7 +120,7 @@ unsigned long __init mmu_mapin_ram(void)
 
        while (s >= LARGE_PAGE_SIZE_4M) {
                pmd_t *pmdp;
-               unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+               unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_HWWRITE;
 
                pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
                pmd_val(*pmdp) = val;
index b6b32487e74057129fc18755d3e8f23264aba69a..83f1551ec2c9182d9299b0504fcdc2138ea3c917 100644 (file)
@@ -128,28 +128,6 @@ void pte_free_finish(void)
 
 #endif /* CONFIG_SMP */
 
-/*
- * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
- */
-static pte_t do_dcache_icache_coherency(pte_t pte)
-{
-       unsigned long pfn = pte_pfn(pte);
-       struct page *page;
-
-       if (unlikely(!pfn_valid(pfn)))
-               return pte;
-       page = pfn_to_page(pfn);
-
-       if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
-               pr_devel("do_dcache_icache_coherency... flushing\n");
-               flush_dcache_icache_page(page);
-               set_bit(PG_arch_1, &page->flags);
-       }
-       else
-               pr_devel("do_dcache_icache_coherency... already clean\n");
-       return __pte(pte_val(pte) | _PAGE_HWEXEC);
-}
-
 static inline int is_exec_fault(void)
 {
        return current->thread.regs && TRAP(current->thread.regs) == 0x400;
@@ -157,49 +135,139 @@ static inline int is_exec_fault(void)
 
 /* We only try to do i/d cache coherency on stuff that looks like
  * reasonably "normal" PTEs. We currently require a PTE to be present
- * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE
+ * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE. We also only do that
+ * on userspace PTEs
  */
 static inline int pte_looks_normal(pte_t pte)
 {
        return (pte_val(pte) &
-               (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE)) ==
-               (_PAGE_PRESENT);
+           (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER)) ==
+           (_PAGE_PRESENT | _PAGE_USER);
 }
 
-#if defined(CONFIG_PPC_STD_MMU)
+struct page * maybe_pte_to_page(pte_t pte)
+{
+       unsigned long pfn = pte_pfn(pte);
+       struct page *page;
+
+       if (unlikely(!pfn_valid(pfn)))
+               return NULL;
+       page = pfn_to_page(pfn);
+       if (PageReserved(page))
+               return NULL;
+       return page;
+}
+
+#if defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0
+
 /* Server-style MMU handles coherency when hashing if HW exec permission
- * is supposed per page (currently 64-bit only). Else, we always flush
- * valid PTEs in set_pte.
+ * is supposed per page (currently 64-bit only). If not, then, we always
+ * flush the cache for valid PTEs in set_pte. Embedded CPU without HW exec
+ * support falls into the same category.
  */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+
+static pte_t set_pte_filter(pte_t pte)
 {
-       return set_pte && pte_looks_normal(pte) &&
-               !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
-                 cpu_has_feature(CPU_FTR_NOEXECUTE));
+       pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+       if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
+                                      cpu_has_feature(CPU_FTR_NOEXECUTE))) {
+               struct page *pg = maybe_pte_to_page(pte);
+               if (!pg)
+                       return pte;
+               if (!test_bit(PG_arch_1, &pg->flags)) {
+                       flush_dcache_icache_page(pg);
+                       set_bit(PG_arch_1, &pg->flags);
+               }
+       }
+       return pte;
 }
-#elif _PAGE_HWEXEC == 0
-/* Embedded type MMU without HW exec support (8xx only so far), we flush
- * the cache for any present PTE
- */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+
+static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
+                                    int dirty)
 {
-       return set_pte && pte_looks_normal(pte);
+       return pte;
 }
-#else
-/* Other embedded CPUs with HW exec support per-page, we flush on exec
- * fault if HWEXEC is not set
+
+#else /* defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0 */
+
+/* Embedded type MMU with HW exec support. This is a bit more complicated
+ * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
+ * instead we "filter out" the exec permission for non clean pages.
  */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+static pte_t set_pte_filter(pte_t pte)
 {
-       return pte_looks_normal(pte) && is_exec_fault() &&
-               !(pte_val(pte) & _PAGE_HWEXEC);
+       struct page *pg;
+
+       /* No exec permission in the first place, move on */
+       if (!(pte_val(pte) & _PAGE_EXEC) || !pte_looks_normal(pte))
+               return pte;
+
+       /* If you set _PAGE_EXEC on weird pages you're on your own */
+       pg = maybe_pte_to_page(pte);
+       if (unlikely(!pg))
+               return pte;
+
+       /* If the page clean, we move on */
+       if (test_bit(PG_arch_1, &pg->flags))
+               return pte;
+
+       /* If it's an exec fault, we flush the cache and make it clean */
+       if (is_exec_fault()) {
+               flush_dcache_icache_page(pg);
+               set_bit(PG_arch_1, &pg->flags);
+               return pte;
+       }
+
+       /* Else, we filter out _PAGE_EXEC */
+       return __pte(pte_val(pte) & ~_PAGE_EXEC);
 }
-#endif
+
+static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
+                                    int dirty)
+{
+       struct page *pg;
+
+       /* So here, we only care about exec faults, as we use them
+        * to recover lost _PAGE_EXEC and perform I$/D$ coherency
+        * if necessary. Also if _PAGE_EXEC is already set, same deal,
+        * we just bail out
+        */
+       if (dirty || (pte_val(pte) & _PAGE_EXEC) || !is_exec_fault())
+               return pte;
+
+#ifdef CONFIG_DEBUG_VM
+       /* So this is an exec fault, _PAGE_EXEC is not set. If it was
+        * an error we would have bailed out earlier in do_page_fault()
+        * but let's make sure of it
+        */
+       if (WARN_ON(!(vma->vm_flags & VM_EXEC)))
+               return pte;
+#endif /* CONFIG_DEBUG_VM */
+
+       /* If you set _PAGE_EXEC on weird pages you're on your own */
+       pg = maybe_pte_to_page(pte);
+       if (unlikely(!pg))
+               goto bail;
+
+       /* If the page is already clean, we move on */
+       if (test_bit(PG_arch_1, &pg->flags))
+               goto bail;
+
+       /* Clean the page and set PG_arch_1 */
+       flush_dcache_icache_page(pg);
+       set_bit(PG_arch_1, &pg->flags);
+
+ bail:
+       return __pte(pte_val(pte) | _PAGE_EXEC);
+}
+
+#endif /* !(defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0) */
 
 /*
  * set_pte stores a linux PTE into the linux page table.
  */
-void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+               pte_t pte)
 {
 #ifdef CONFIG_DEBUG_VM
        WARN_ON(pte_present(*ptep));
@@ -208,9 +276,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte
         * this context might not have been activated yet when this
         * is called.
         */
-       pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
-       if (pte_need_exec_flush(pte, 1))
-               pte = do_dcache_icache_coherency(pte);
+       pte = set_pte_filter(pte);
 
        /* Perform the setting of the PTE */
        __set_pte_at(mm, addr, ptep, pte, 0);
@@ -227,8 +293,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
                          pte_t *ptep, pte_t entry, int dirty)
 {
        int changed;
-       if (!dirty && pte_need_exec_flush(entry, 0))
-               entry = do_dcache_icache_coherency(entry);
+       entry = set_access_flags_filter(entry, vma, dirty);
        changed = !pte_same(*(ptep), entry);
        if (changed) {
                if (!(vma->vm_flags & VM_HUGETLB))
index 5422169626ba8f7baa5b0f1a4930ee57a91e246f..cb96cb2e17cc0560e947550690013a342f63929c 100644 (file)
@@ -142,7 +142,7 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
                flags |= _PAGE_DIRTY | _PAGE_HWWRITE;
 
        /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
-       flags &= ~(_PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC);
+       flags &= ~(_PAGE_USER | _PAGE_EXEC);
 
        return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
index 10d524ded7b2bff624bda56bc1b3fab3e4737e2a..cd92f62f9cf5eaf4220690bc1099b8e67efcf13f 100644 (file)
 
        /* We do the user/kernel test for the PID here along with the RW test
         */
-       li      r11,_PAGE_PRESENT|_PAGE_HWEXEC  /* Base perm */
+       li      r11,_PAGE_PRESENT|_PAGE_EXEC    /* Base perm */
        oris    r11,r11,_PAGE_ACCESSED@h
 
        cmpldi  cr0,r15,0                       /* Check for user region */
@@ -256,7 +256,7 @@ normal_tlb_miss_done:
 
 normal_tlb_miss_access_fault:
        /* We need to check if it was an instruction miss */
-       andi.   r10,r11,_PAGE_HWEXEC
+       andi.   r10,r11,_PAGE_EXEC
        bne     1f
        ld      r14,EX_TLB_DEAR(r12)
        ld      r15,EX_TLB_ESR(r12)