static inline void _l4x_pmd_clear(struct mm_struct *mm, unsigned long addr, pmd_t pmdval) { /* Invalidate page */ l4x_flush_page(mm, pmd_val(pmdval) & PMD_PAGE_MASK & PHYSICAL_PAGE_MASK, addr, PMD_SHIFT, L4_FPAGE_RWX, _RET_IP_); }
unsigned long l4x_set_pte(struct mm_struct *mm, unsigned long addr, pte_t old, pte_t pteval) { /* * Check if any invalidation is necessary * * Invalidation (flush) necessary if: * old page was present * new page is not present OR * new page has another physical address OR * new page has another protection OR * new page has other access attributes */ /* old was present && new not -> flush */ int flush_rights = L4_FPAGE_RWX; #if 0 if ((pte_val(old) & PAGE_MASK) != (pte_val(pteval) & PAGE_MASK)) printk("spte %x->%x\n", pte_val(old), pte_val(pteval)); #endif if (pte_present(pteval)) { /* new page is present, * now we have to find out what has changed */ if (((pte_val(old) ^ pte_val(pteval)) & PAGE_MASK) || (pte_young(old) && !pte_young(pteval))) { /* physical page frame changed * || access attribute changed -> flush */ /* flush is the default */ //pteval.pte_low &= ~_PAGE_MAPPED; pteval = __pte(pte_val(pteval) & ~_PAGE_MAPPED); } else if ((pte_write(old) && !pte_write(pteval)) || (pte_dirty(old) && !pte_dirty(pteval))) { /* Protection changed from r/w to ro * or page now clean -> remap */ flush_rights = L4_FPAGE_W; check_pte_mapped(old, pteval, "RW->RO"); } else { /* nothing changed, simply return */ check_pte_mapped(old, pteval, "NoChg"); return pte_val(pteval); } } /* Ok, now actually flush or remap the page */ L4XV_FN_v(l4x_flush_page(mm, pte_val(old), addr, PAGE_SHIFT, flush_rights)); return pte_val(pteval); }
unsigned long l4x_set_pmd(struct mm_struct *mm, unsigned long addr, pmd_t old, pmd_t pmdval) { /* * Check if any invalidation is necessary * * Invalidation (flush) necessary if: * old page was present * new page is not present OR * new page has another physical address OR * new page has another protection OR * new page has other access attributes */ /* old was present && new not -> flush */ int flush_rights = L4_FPAGE_RWX; BUG_ON(!pmd_large(old)); if (pmd_present(pmdval)) { /* new page is present, * now we have to find out what has changed */ if (((pmd_val(old) ^ pmd_val(pmdval)) & PMD_PAGE_MASK & PHYSICAL_PAGE_MASK) || (pmd_young(old) && !pmd_young(pmdval))) { /* physical page frame changed * || access attribute changed -> flush */ /* flush is the default */ } else if ((pmd_write(old) && !pmd_write(pmdval)) || (pmd_flags(old) & ~pmd_flags(pmdval) & (_PAGE_DIRTY | _PAGE_SOFT_DIRTY))) { /* Protection changed from r/w to ro * or page now clean -> remap */ flush_rights = L4_FPAGE_W; } else { /* nothing changed, simply return */ return pmd_val(pmdval); } } /* Ok, now actually flush or remap the page */ l4x_flush_page(mm, pmd_val(old) & PMD_PAGE_MASK & PHYSICAL_PAGE_MASK, addr, PMD_SHIFT, flush_rights, _RET_IP_); return pmd_val(pmdval); }
unsigned long l4x_set_pte(struct mm_struct *mm, unsigned long addr, pte_t old, pte_t pteval) { /* * Check if any invalidation is necessary * * Invalidation (flush) necessary if: * old page was present * new page is not present OR * new page has another physical address OR * new page has another protection OR * new page has other access attributes */ /* old was present && new not -> flush */ int flush_rights = L4_FPAGE_RWX; if (pte_present(pteval)) { /* new page is present, * now we have to find out what has changed */ if (((pte_val(old) ^ pte_val(pteval)) & PAGE_MASK) || (pte_young(old) && !pte_young(pteval))) { /* physical page frame changed * || access attribute changed -> flush */ /* flush is the default */ } else if ((pte_write(old) && !pte_write(pteval)) || (pte_dirty(old) && !pte_dirty(pteval))) { /* Protection changed from r/w to ro * or page now clean -> remap */ flush_rights = L4_FPAGE_W; } else { /* nothing changed, simply return */ return pte_val(pteval); } } /* Ok, now actually flush or remap the page */ l4x_flush_page(mm, pte_val(old), addr, PAGE_SHIFT, flush_rights); return pte_val(pteval); }
void l4x_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t pteval) { /* Invalidate page */ l4x_flush_page(mm, pte_val(pteval) & L4X_PHYSICAL_PAGE_MASK, addr, PAGE_SHIFT, L4_FPAGE_RWX, _RET_IP_); }
void l4x_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t pteval) { /* Invalidate page */ l4x_flush_page(mm, pte_val(pteval), addr, PAGE_SHIFT, L4_FPAGE_RWX); }