Changeset View
Standalone View
sys/i386/i386/pmap.c
Show First 20 Lines • Show All 3,795 Lines • ▼ Show 20 Lines | else if ((origpte & PG_NX) != 0 || (newpte & PG_NX) == 0) { | ||||
* This PTE change does not require TLB invalidation. | * This PTE change does not require TLB invalidation. | ||||
*/ | */ | ||||
goto unchanged; | goto unchanged; | ||||
} | } | ||||
#endif | #endif | ||||
if ((origpte & PG_A) != 0) | if ((origpte & PG_A) != 0) | ||||
pmap_invalidate_page_int(pmap, va); | pmap_invalidate_page_int(pmap, va); | ||||
} else | } else | ||||
pte_store(pte, newpte); | pte_store_zero(pte, newpte); | ||||
unchanged: | unchanged: | ||||
#if VM_NRESERVLEVEL > 0 | #if VM_NRESERVLEVEL > 0 | ||||
/* | /* | ||||
* If both the page table page and the reservation are fully | * If both the page table page and the reservation are fully | ||||
* populated, then attempt promotion. | * populated, then attempt promotion. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 286 Lines • ▼ Show 20 Lines | pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, | ||||
if ((m->oflags & VPO_UNMANAGED) == 0) | if ((m->oflags & VPO_UNMANAGED) == 0) | ||||
newpte |= PG_MANAGED; | newpte |= PG_MANAGED; | ||||
#ifdef PMAP_PAE_COMP | #ifdef PMAP_PAE_COMP | ||||
if ((prot & VM_PROT_EXECUTE) == 0 && !i386_read_exec) | if ((prot & VM_PROT_EXECUTE) == 0 && !i386_read_exec) | ||||
newpte |= pg_nx; | newpte |= pg_nx; | ||||
#endif | #endif | ||||
if (pmap != kernel_pmap) | if (pmap != kernel_pmap) | ||||
newpte |= PG_U; | newpte |= PG_U; | ||||
pte_store(pte, newpte); | pte_store_zero(pte, newpte); | ||||
markj: Hmm, I think you can unconditionally use pte_store_z() here since the old entry is known to be… | |||||
Done Inline ActionsBut then it returns the question of random pmap_kextract() seeing torn write. kib: But then it returns the question of random pmap_kextract() seeing torn write.
(I think that it… | |||||
Not Done Inline ActionsDon't you still have this problem in the pmap_enter() change then? I suspect it is a bug to call pmap_kextract() on an unmapped address, and this reasoning can be used to justify the use of pte_store_z() on invalid entries, even in the kernel pmap. I believe the issue is only with stores that modify a valid PTE or PDE in the kernel pmap. markj: Don't you still have this problem in the pmap_enter() change then?
I suspect it is a bug to… | |||||
Done Inline ActionsI would have the answer to this question if Peter can reproduce the torn write issue with the patch. It is not even clear to me if e.g. pmap_kenter() or pmap_qenter() can use pte_store_zero(). kib: I would have the answer to this question if Peter can reproduce the torn write issue with the… | |||||
Not Done Inline ActionsDo either of those routines get used often on i386? markj: Do either of those routines get used often on i386? | |||||
Done Inline Actionspmap_qenter() absolutely, it is used when buffer needs to be mapped, which is always for a buffer with metadata. pmap_kenter() not so much, AFAIR. kib: pmap_qenter() absolutely, it is used when buffer needs to be mapped, which is always for a… | |||||
sched_unpin(); | sched_unpin(); | ||||
return (mpte); | return (mpte); | ||||
} | } | ||||
/* | /* | ||||
* Make a temporary mapping for a physical address. This is only intended | * Make a temporary mapping for a physical address. This is only intended | ||||
* to be used for panic dumps. | * to be used for panic dumps. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 2,085 Lines • Show Last 20 Lines |
Hmm, I think you can unconditionally use pte_store_z() here since the old entry is known to be invalid.