tree 5b1a763061d68caef26ec85d55404d868bab7a74
parent 0c541b4406a68e74d94ddb667c69d9e03bce8681
author Kumar Gala <[EMAIL PROTECTED]> Sun, 17 Apr 2005 05:24:20 -0700
committer Linus Torvalds <[EMAIL PROTECTED]> Sun, 17 Apr 2005 05:24:20 -0700

[PATCH] ppc32: Fix pte_update for 64-bit PTEs

While the existing pte_update code handled atomically modifying a 64-bit PTE,
it did not return all 64-bits of the PTE before it was modified.  This causes
problems in some places that expect the full PTE to be returned, like
ptep_get_and_clear().

Created a new pte_update function that is conditional on CONFIG_PTE_64BIT.  It
atomically reads the low PTE word which all PTE flags are required to be in
and returns a premodified full 64-bit PTE.

Since we now have an explicit 64-bit PTE version of pte_update we can also
remove the hack that existed to get the low PTE word regardless of size.

Signed-off-by: Kumar Gala <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>

 asm-ppc/pgtable.h |   29 +++++++++++++++++++++++++----
 1 files changed, 25 insertions(+), 4 deletions(-)

Index: include/asm-ppc/pgtable.h
===================================================================
--- 869506b6c3f7c00ac13f2aa80c35fb5e229cc329/include/asm-ppc/pgtable.h  
(mode:100644 sha1:19dfb7abaa2189e6d11a56da91ee8c8c9b3ccca3)
+++ 5b1a763061d68caef26ec85d55404d868bab7a74/include/asm-ppc/pgtable.h  
(mode:100644 sha1:2e88cd9feffe953ae2f447223f48237b80de869a)
@@ -526,10 +526,10 @@
  * Atomic PTE updates.
  *
  * pte_update clears and sets bit atomically, and returns
- * the old pte value.
- * The ((unsigned long)(p+1) - 4) hack is to get to the least-significant
- * 32 bits of the PTE regardless of whether PTEs are 32 or 64 bits.
+ * the old pte value.  In the 64-bit PTE case we lock around the
+ * low PTE word since we expect ALL flag bits to be there
  */
+#ifndef CONFIG_PTE_64BIT
 static inline unsigned long pte_update(pte_t *p, unsigned long clr,
                                       unsigned long set)
 {
@@ -543,10 +543,31 @@
 "      stwcx.  %1,0,%3\n\
        bne-    1b"
        : "=&r" (old), "=&r" (tmp), "=m" (*p)
-       : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p)
+       : "r" (p), "r" (clr), "r" (set), "m" (*p)
        : "cc" );
        return old;
 }
+#else
+static inline unsigned long long pte_update(pte_t *p, unsigned long clr,
+                                      unsigned long set)
+{
+       unsigned long long old;
+       unsigned long tmp;
+
+       __asm__ __volatile__("\
+1:     lwarx   %L0,0,%4\n\
+       lwzx    %0,0,%3\n\
+       andc    %1,%L0,%5\n\
+       or      %1,%1,%6\n"
+       PPC405_ERR77(0,%3)
+"      stwcx.  %1,0,%4\n\
+       bne-    1b"
+       : "=&r" (old), "=&r" (tmp), "=m" (*p)
+       : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
+       : "cc" );
+       return old;
+}
+#endif
 
 /*
  * set_pte stores a linux PTE into the linux page table.
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to