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;
    }
}
예제 #2
0
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();
	}
}