#define flush_icache_page(vma,page)    do { } while (0)
 
 /*
- * flush_cache_vmap() is used when creating mappings (eg, via vmap,
- * vmalloc, ioremap etc) in kernel space for pages.  On non-VIPT
- * caches, since the direct-mappings of these pages may contain cached
- * data, we need to do a full cache flush to ensure that writebacks
- * don't corrupt data placed into these pages via the new mappings.
+ * Not required on AArch64 (PIPT or VIPT non-aliasing D-cache).
  */
 static inline void flush_cache_vmap(unsigned long start, unsigned long end)
 {
-       /*
-        * set_pte_at() called from vmap_pte_range() does not
-        * have a DSB after cleaning the cache line.
-        */
-       dsb(ish);
 }
 
 static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
 
 
 #define pte_valid_user(pte) \
        ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
+#define pte_valid_not_user(pte) \
+       ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID)
 
 static inline pte_t pte_wrprotect(pte_t pte)
 {
 static inline void set_pte(pte_t *ptep, pte_t pte)
 {
        *ptep = pte;
+
+       /*
+        * Only if the new pte is valid and kernel, otherwise TLB maintenance
+        * or update_mmu_cache() have the necessary barriers.
+        */
+       if (pte_valid_not_user(pte)) {
+               dsb(ishst);
+               isb();
+       }
 }
 
 extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
 {
        *pmdp = pmd;
        dsb(ishst);
+       isb();
 }
 
 static inline void pmd_clear(pmd_t *pmdp)
 {
        *pudp = pud;
        dsb(ishst);
+       isb();
 }
 
 static inline void pud_clear(pud_t *pudp)
 
        for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12))
                asm("tlbi vaae1is, %0" : : "r"(addr));
        dsb(ish);
+       isb();
 }
 
 /*
                                    unsigned long addr, pte_t *ptep)
 {
        /*
-        * set_pte() does not have a DSB, so make sure that the page table
-        * write is visible.
+        * set_pte() does not have a DSB for user mappings, so make sure that
+        * the page table write is visible.
         */
        dsb(ishst);
 }