/* * This is called when relaxing access to a PTE. It's also called in the page * fault path when we don't hit any of the major fault cases, ie, a minor * update of _PAGE_ACCESSED, _PAGE_DIRTY, etc... The generic code will have * handled those two for us, we additionally deal with missing execute * permission here on some processors */ 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); changed = !pte_same(*(ptep), entry); if (changed) { assert_pte_locked(vma->vm_mm, address); __ptep_set_access_flags(ptep, entry); flush_tlb_page_nohash(vma, address); } return changed; }
/* * 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) { #ifdef CONFIG_DEBUG_VM WARN_ON(pte_present(*ptep)); #endif /* Note: mm->context.id might not yet have been assigned as * 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, addr); /* Perform the setting of the PTE */ __set_pte_at(mm, addr, ptep, pte, 0); }