Index: sys/amd64/amd64/pmap.c =================================================================== --- sys/amd64/amd64/pmap.c +++ sys/amd64/amd64/pmap.c @@ -4855,8 +4855,8 @@ * within a 2MB page. */ firstpte = (pt_entry_t *)PHYS_TO_DMAP(*pde & PG_FRAME); -setpde: newpde = *firstpte; +setpde: if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V)) { atomic_add_long(&pmap_pde_p_failures, 1); CTR2(KTR_PMAP, "pmap_promote_pde: failure for va %#lx" @@ -4868,7 +4868,7 @@ * When PG_M is already clear, PG_RW can be cleared without * a TLB invalidation. */ - if (!atomic_cmpset_long(firstpte, newpde, newpde & ~PG_RW)) + if (!atomic_fcmpset_long(firstpte, &newpde, newpde & ~PG_RW)) goto setpde; newpde &= ~PG_RW; } @@ -4880,8 +4880,8 @@ */ pa = (newpde & (PG_PS_FRAME | PG_A | PG_V)) + NBPDR - PAGE_SIZE; for (pte = firstpte + NPTEPG - 1; pte > firstpte; pte--) { -setpte: oldpte = *pte; +setpte: if ((oldpte & (PG_FRAME | PG_A | PG_V)) != pa) { atomic_add_long(&pmap_pde_p_failures, 1); CTR2(KTR_PMAP, "pmap_promote_pde: failure for va %#lx" @@ -4893,7 +4893,7 @@ * When PG_M is already clear, PG_RW can be cleared * without a TLB invalidation. */ - if (!atomic_cmpset_long(pte, oldpte, oldpte & ~PG_RW)) + if (!atomic_fcmpset_long(pte, &oldpte, oldpte & ~PG_RW)) goto setpte; oldpte &= ~PG_RW; CTR2(KTR_PMAP, "pmap_promote_pde: protect for va %#lx" Index: sys/i386/i386/pmap.c =================================================================== --- sys/i386/i386/pmap.c +++ sys/i386/i386/pmap.c @@ -3531,8 +3531,8 @@ * within a 2- or 4MB page. */ firstpte = pmap_pte_quick(pmap, trunc_4mpage(va)); -setpde: newpde = *firstpte; +setpde: if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V)) { pmap_pde_p_failures++; CTR2(KTR_PMAP, "pmap_promote_pde: failure for va %#x" @@ -3550,7 +3550,7 @@ * When PG_M is already clear, PG_RW can be cleared without * a TLB invalidation. */ - if (!atomic_cmpset_int((u_int *)firstpte, newpde, newpde & + if (!atomic_fcmpset_int((u_int *)firstpte, &newpde, newpde & ~PG_RW)) goto setpde; newpde &= ~PG_RW; @@ -3563,8 +3563,8 @@ */ pa = (newpde & (PG_PS_FRAME | PG_A | PG_V)) + NBPDR - PAGE_SIZE; for (pte = firstpte + NPTEPG - 1; pte > firstpte; pte--) { -setpte: oldpte = *pte; +setpte: if ((oldpte & (PG_FRAME | PG_A | PG_V)) != pa) { pmap_pde_p_failures++; CTR2(KTR_PMAP, "pmap_promote_pde: failure for va %#x" @@ -3576,7 +3576,7 @@ * When PG_M is already clear, PG_RW can be cleared * without a TLB invalidation. */ - if (!atomic_cmpset_int((u_int *)pte, oldpte, + if (!atomic_fcmpset_int((u_int *)pte, &oldpte, oldpte & ~PG_RW)) goto setpte; oldpte &= ~PG_RW;