static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) { unsigned index = pgd_index(address); pgd_t *pgd_k; pud_t *pud, *pud_k; pmd_t *pmd, *pmd_k; pgd += index; pgd_k = init_mm.pgd + index; if (!pgd_present(*pgd_k)) return NULL; /* * set_pgd(pgd, *pgd_k); here would be useless on PAE * and redundant with the set_pmd() on non-PAE. As would * set_pud. */ pud = pud_offset(pgd, address); pud_k = pud_offset(pgd_k, address); if (!pud_present(*pud_k)) return NULL; pmd = pmd_offset(pud, address); pmd_k = pmd_offset(pud_k, address); if (!pmd_present(*pmd_k)) return NULL; if (!pmd_present(*pmd)) #ifndef CONFIG_XEN set_pmd(pmd, *pmd_k); #else /* * When running on Xen we must launder *pmd_k through * pmd_val() to ensure that _PAGE_PRESENT is correctly set. */ set_pmd(pmd, __pmd(pmd_val(*pmd_k))); #endif else BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); return pmd_k; }