]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/include/asm/pgtable-ppc32.h
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / arch / powerpc / include / asm / pgtable-ppc32.h
index c2e58b41bc78f187dc39af2d247b1f9fcf396821..6ab7c67cb5ab6355ba453e4832ad55bcdb03ec85 100644 (file)
@@ -369,7 +369,12 @@ extern int icache_44x_need_flush;
 #define _PAGE_RW       0x400   /* software: user write access allowed */
 #define _PAGE_SPECIAL  0x800   /* software: Special page */
 
+#ifdef CONFIG_PTE_64BIT
+/* We never clear the high word of the pte */
+#define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE)
+#else
 #define _PTE_NONE_MASK _PAGE_HASHPTE
+#endif
 
 #define _PMD_PRESENT   0
 #define _PMD_PRESENT_MASK (PAGE_MASK)
@@ -426,11 +431,11 @@ extern int icache_44x_need_flush;
 #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
 
 
-#define PAGE_PROT_BITS __pgprot(_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
-                                _PAGE_WRITETHRU | _PAGE_ENDIAN | \
-                                _PAGE_USER | _PAGE_ACCESSED | \
-                                _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
-                                _PAGE_EXEC | _PAGE_HWEXEC)
+#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
+                        _PAGE_WRITETHRU | _PAGE_ENDIAN | \
+                        _PAGE_USER | _PAGE_ACCESSED | \
+                        _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
+                        _PAGE_EXEC | _PAGE_HWEXEC)
 /*
  * Note: the _PAGE_COHERENT bit automatically gets set in the hardware
  * PTE if CONFIG_SMP is defined (hash_page does this); there is no need
@@ -565,9 +570,9 @@ static inline pte_t pte_mkyoung(pte_t pte) {
        pte_val(pte) |= _PAGE_ACCESSED; return pte; }
 static inline pte_t pte_mkspecial(pte_t pte) {
        pte_val(pte) |= _PAGE_SPECIAL; return pte; }
-static inline unsigned long pte_pgprot(pte_t pte)
+static inline pgprot_t pte_pgprot(pte_t pte)
 {
-       return __pgprot(pte_val(pte)) & PAGE_PROT_BITS;
+       return __pgprot(pte_val(pte) & PAGE_PROT_BITS);
 }
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
@@ -587,6 +592,10 @@ extern int flush_hash_pages(unsigned context, unsigned long va,
 extern void add_hash_page(unsigned context, unsigned long va,
                          unsigned long pmdval);
 
+/* Flush an entry from the TLB/hash table */
+extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
+                            unsigned long address);
+
 /*
  * Atomic PTE updates.
  *
@@ -665,9 +674,13 @@ static inline unsigned long long pte_update(pte_t *p,
 static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
                              pte_t *ptep, pte_t pte)
 {
-#if _PAGE_HASHPTE != 0
+#if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
        pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
 #elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
+#if _PAGE_HASHPTE != 0
+       if (pte_val(*ptep) & _PAGE_HASHPTE)
+               flush_hash_entry(mm, ptep, addr);
+#endif
        __asm__ __volatile__("\
                stw%U0%X0 %2,%0\n\
                eieio\n\
@@ -675,7 +688,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
        : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
        : "r" (pte) : "memory");
 #else
-       *ptep = pte;
+       *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+                     | (pte_val(pte) & ~_PAGE_HASHPTE));
 #endif
 }