static void change_page_attr(unsigned long addr, int numpages, pte_t (*set) (pte_t)) { pte_t *ptep, pte; pmd_t *pmdp; pud_t *pudp; pgd_t *pgdp; int i; for (i = 0; i < numpages; i++) { pgdp = pgd_offset(&init_mm, addr); pudp = pud_offset(pgdp, addr); pmdp = pmd_offset(pudp, addr); if (pmd_huge(*pmdp)) { WARN_ON_ONCE(1); continue; } ptep = pte_offset_kernel(pmdp, addr); pte = *ptep; pte = set(pte); ptep_invalidate(&init_mm, addr, ptep); *ptep = pte; addr += PAGE_SIZE; } }
void kernel_map_pages(struct page *page, int numpages, int enable) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte; unsigned long address; int i; for (i = 0; i < numpages; i++) { address = page_to_phys(page + i); pgd = pgd_offset_k(address); pud = pud_offset(pgd, address); pmd = pmd_offset(pud, address); pte = pte_offset_kernel(pmd, address); if (!enable) { ptep_invalidate(&init_mm, address, pte); continue; } *pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW)); /* Flush cpu write queue. */ mb(); } }