diff options
author | alc <alc@FreeBSD.org> | 2004-10-08 08:23:43 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-10-08 08:23:43 +0000 |
commit | 417a40f2bff86acecbf99e0fde8bd75b42920fa4 (patch) | |
tree | 7a5a0495f446462dd1a370313683c21899917462 /sys/i386/include/pmap.h | |
parent | 8b1be96ee507ff704291bae4e80e020485ada346 (diff) | |
download | FreeBSD-src-417a40f2bff86acecbf99e0fde8bd75b42920fa4.zip FreeBSD-src-417a40f2bff86acecbf99e0fde8bd75b42920fa4.tar.gz |
Make pte_load_store() an atomic operation in all cases, not just i386 PAE.
Restructure pmap_enter() to prevent the loss of a page modified (PG_M) bit
in a race between processors. (This restructuring assumes the newly atomic
pte_load_store() for correct operation.)
Reviewed by: tegge@
PR: i386/61852
Diffstat (limited to 'sys/i386/include/pmap.h')
-rw-r--r-- | sys/i386/include/pmap.h | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h index eb7b53b..7c54006 100644 --- a/sys/i386/include/pmap.h +++ b/sys/i386/include/pmap.h @@ -236,6 +236,8 @@ pte_load_store(pt_entry_t *ptep, pt_entry_t v) #define pte_load_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL) +#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte) + #else /* PAE */ static __inline pt_entry_t @@ -252,17 +254,27 @@ pte_load_store(pt_entry_t *ptep, pt_entry_t pte) { pt_entry_t r; - r = *ptep; - *ptep = pte; + __asm __volatile( + "xchgl %0,%1" + : "=m" (*ptep), + "=r" (r) + : "1" (pte), + "m" (*ptep)); return (r); } #define pte_load_clear(pte) atomic_readandclear_int(pte) +static __inline void +pte_store(pt_entry_t *ptep, pt_entry_t pte) +{ + + *ptep = pte; +} + #endif /* PAE */ -#define pte_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL) -#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte) +#define pte_clear(ptep) pte_store((ptep), (pt_entry_t)0ULL) #define pde_store(pdep, pde) pte_store((pdep), (pde)) |