static bool kvm_mips_flush_gpa_pmd(pmd_t *pmd, unsigned long start_gpa, unsigned long end_gpa) { pte_t *pte; unsigned long end = ~0ul; int i_min = __pmd_offset(start_gpa); int i_max = __pmd_offset(end_gpa); bool safe_to_remove = (i_min == 0 && i_max == PTRS_PER_PMD - 1); int i; for (i = i_min; i <= i_max; ++i, start_gpa = 0) { if (!pmd_present(pmd[i])) continue; pte = pte_offset(pmd + i, 0); if (i == i_max) end = end_gpa; if (kvm_mips_flush_gpa_pte(pte, start_gpa, end)) { pmd_clear(pmd + i); pte_free_kernel(NULL, pte); } 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; } }