purge_tlb_end(flags);
 }
 
+extern void __update_cache(pte_t pte);
+
 /* Certain architectures need to do special things when PTEs
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
 #define set_pte(pteptr, pteval)                        \
        do {                                    \
                *(pteptr) = (pteval);           \
-               barrier();                      \
+               mb();                           \
        } while(0)
 
 #define set_pte_at(mm, addr, pteptr, pteval)   \
        do {                                    \
+               if (pte_present(pteval) &&      \
+                   pte_user(pteval))           \
+                       __update_cache(pteval); \
                *(pteptr) = (pteval);           \
                purge_tlb_entries(mm, addr);    \
        } while (0)
 
 #define pte_none(x)     (pte_val(x) == 0)
 #define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
+#define pte_user(x)    (pte_val(x) & _PAGE_USER)
 #define pte_clear(mm, addr, xp)  set_pte_at(mm, addr, xp, __pte(0))
 
 #define pmd_flag(x)    (pmd_val(x) & PxD_FLAG_MASK)
 
 #define PG_dcache_dirty         PG_arch_1
 
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
+#define update_mmu_cache(vms,addr,ptep) __update_cache(*ptep)
 
 /* Encode and de-code a swap entry */
 
 
 #define pfn_va(pfn)    __va(PFN_PHYS(pfn))
 
 void
-update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
+__update_cache(pte_t pte)
 {
-       unsigned long pfn = pte_pfn(*ptep);
+       unsigned long pfn = pte_pfn(pte);
        struct page *page;
 
        /* We don't have pte special.  As a result, we can be called with