diff options
Diffstat (limited to 'include/asm-ppc/pgtable.h')
-rw-r--r-- | include/asm-ppc/pgtable.h | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 19dfb7abaa21..2e88cd9feffe 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h | |||
@@ -526,10 +526,10 @@ extern void add_hash_page(unsigned context, unsigned long va, | |||
526 | * Atomic PTE updates. | 526 | * Atomic PTE updates. |
527 | * | 527 | * |
528 | * pte_update clears and sets bit atomically, and returns | 528 | * pte_update clears and sets bit atomically, and returns |
529 | * the old pte value. | 529 | * the old pte value. In the 64-bit PTE case we lock around the |
530 | * The ((unsigned long)(p+1) - 4) hack is to get to the least-significant | 530 | * low PTE word since we expect ALL flag bits to be there |
531 | * 32 bits of the PTE regardless of whether PTEs are 32 or 64 bits. | ||
532 | */ | 531 | */ |
532 | #ifndef CONFIG_PTE_64BIT | ||
533 | static inline unsigned long pte_update(pte_t *p, unsigned long clr, | 533 | static inline unsigned long pte_update(pte_t *p, unsigned long clr, |
534 | unsigned long set) | 534 | unsigned long set) |
535 | { | 535 | { |
@@ -543,10 +543,31 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, | |||
543 | " stwcx. %1,0,%3\n\ | 543 | " stwcx. %1,0,%3\n\ |
544 | bne- 1b" | 544 | bne- 1b" |
545 | : "=&r" (old), "=&r" (tmp), "=m" (*p) | 545 | : "=&r" (old), "=&r" (tmp), "=m" (*p) |
546 | : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p) | 546 | : "r" (p), "r" (clr), "r" (set), "m" (*p) |
547 | : "cc" ); | 547 | : "cc" ); |
548 | return old; | 548 | return old; |
549 | } | 549 | } |
550 | #else | ||
551 | static inline unsigned long long pte_update(pte_t *p, unsigned long clr, | ||
552 | unsigned long set) | ||
553 | { | ||
554 | unsigned long long old; | ||
555 | unsigned long tmp; | ||
556 | |||
557 | __asm__ __volatile__("\ | ||
558 | 1: lwarx %L0,0,%4\n\ | ||
559 | lwzx %0,0,%3\n\ | ||
560 | andc %1,%L0,%5\n\ | ||
561 | or %1,%1,%6\n" | ||
562 | PPC405_ERR77(0,%3) | ||
563 | " stwcx. %1,0,%4\n\ | ||
564 | bne- 1b" | ||
565 | : "=&r" (old), "=&r" (tmp), "=m" (*p) | ||
566 | : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p) | ||
567 | : "cc" ); | ||
568 | return old; | ||
569 | } | ||
570 | #endif | ||
550 | 571 | ||
551 | /* | 572 | /* |
552 | * set_pte stores a linux PTE into the linux page table. | 573 | * set_pte stores a linux PTE into the linux page table. |