summaryrefslogtreecommitdiffstats
path: root/sys/i386/include
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-10-08 08:23:43 +0000
committeralc <alc@FreeBSD.org>2004-10-08 08:23:43 +0000
commit417a40f2bff86acecbf99e0fde8bd75b42920fa4 (patch)
tree7a5a0495f446462dd1a370313683c21899917462 /sys/i386/include
parent8b1be96ee507ff704291bae4e80e020485ada346 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/i386/include/pmap.h20
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))
OpenPOWER on IntegriCloud