powerpc/pmap: Fix pte_find_next() iterators for booke64 pmap
After r361988 fixed the reference count leak on booke64, it became possible for an iteration somewhere in the middle of a page to become stale, with the page vanishing (correctly) due to all PTEs on that page going away. pte_find_next() would start at that iterator, and move along 'higher' order directory pages until it finds a valid one, without zeroing out the lower order pages. For instance: /* Find next pte at or above 0x10002000. */ pte = pte_find_next(pmap, &(0x10002000)); pte_remove(pmap, pte); /* This pte was the last reference in the page table page, page is * gone. */ pte = pte_find_next(pmap, 0x10002000); /* pte_find_next will see 0x10002000's page is gone, and jump to the * next one, but starting iteration at the '0x2000' slot, skipping * 0x0000 and 0x1000. */ This caused some processes, like git, to trip the KASSERT() in pmap_release(). Fix this by zeroing all lower order iterators at each level.
This commit is contained in:
parent
4149c6a3ec
commit
ae672aa5e3
@ -220,12 +220,13 @@ pte_find_next(pmap_t pmap, vm_offset_t *pva)
|
||||
k = PDIR_IDX(va);
|
||||
l = PTBL_IDX(va);
|
||||
pm_root = pmap->pm_root;
|
||||
|
||||
/* truncate the VA for later. */
|
||||
va &= ~((1UL << (PG_ROOT_H + 1)) - 1);
|
||||
for (; i < PG_ROOT_NENTRIES; i++, j = 0) {
|
||||
for (; i < PG_ROOT_NENTRIES; i++, j = 0, k = 0, l = 0) {
|
||||
if (pm_root[i] == 0)
|
||||
continue;
|
||||
for (; j < PDIR_L1_NENTRIES; j++, k = 0) {
|
||||
for (; j < PDIR_L1_NENTRIES; j++, k = 0, l = 0) {
|
||||
if (pm_root[i][j] == 0)
|
||||
continue;
|
||||
for (; k < PDIR_NENTRIES; k++, l = 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user