static bool kvm_mips_flush_gpa_pud(pud_t *pud, unsigned long start_gpa, unsigned long end_gpa) { pmd_t *pmd; unsigned long end = ~0ul; int i_min = __pud_offset(start_gpa); int i_max = __pud_offset(end_gpa); bool safe_to_remove = (i_min == 0 && i_max == PTRS_PER_PUD - 1); int i; for (i = i_min; i <= i_max; ++i, start_gpa = 0) { if (!pud_present(pud[i])) continue; pmd = pmd_offset(pud + i, 0); if (i == i_max) end = end_gpa; if (kvm_mips_flush_gpa_pmd(pmd, start_gpa, end)) { pud_clear(pud + i); pmd_free(NULL, pmd); } else { safe_to_remove = false; } } return safe_to_remove; }
void __init page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte = NULL; int i, j, k; unsigned long vaddr; vaddr = start; i = __pgd_offset(vaddr); j = __pud_offset(vaddr); k = __pmd_offset(vaddr); pgd = pgd_base + i; for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { pud = (pud_t *)pgd; for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) { pmd = one_md_table_init(pud); #ifndef __PAGETABLE_PMD_FOLDED pmd += k; #endif for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { pte = page_table_kmap_check(one_page_table_init(pmd), pmd, vaddr, pte); vaddr += PMD_SIZE; } k = 0; } j = 0; } }