/*
* We take the easy way out of this problem - we make the
* PTE uncacheable. However, we leave the write buffer on.
+ *
+ * Note that the pte lock held when calling update_mmu_cache must also
+ * guard the pte (somewhere else in the same mm) that we modify here.
+ * Therefore those configurations which might call adjust_pte (those
+ * without CONFIG_CPU_CACHE_VIPT) cannot support split page_table_lock.
*/
static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
{
if (pte_present(entry) && pte_val(entry) & shared_pte_mask) {
flush_cache_page(vma, address, pte_pfn(entry));
pte_val(entry) &= ~shared_pte_mask;
- set_pte(pte, entry);
+ set_pte_at(vma->vm_mm, address, pte, entry);
flush_tlb_page(vma, address);
ret = 1;
}
flush_cache_page(vma, addr, pfn);
}
-void __flush_dcache_page(struct address_space *mapping, struct page *page);
-
/*
* Take care of architecture specific things when placing a new PTE into
* a page table, or changing an existing PTE. Basically, there are two
* 2. If we have multiple shared mappings of the same space in
* an object, we need to deal with the cache aliasing issues.
*
- * Note that the page_table_lock will be held.
+ * Note that the pte lock will be held.
*/
void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
{
page = pfn_to_page(pfn);
mapping = page_mapping(page);
if (mapping) {
+#ifndef CONFIG_SMP
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
if (dirty)
__flush_dcache_page(mapping, page);
+#endif
if (cache_is_vivt())
make_coherent(mapping, vma, addr, pfn);
+ else if (vma->vm_flags & VM_EXEC)
+ __flush_icache_all();
}
}