]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/mm/pgtable_64.c
powerpc/mm: Replace _PAGE_USER with _PAGE_PRIVILEGED
[karo-tx-linux.git] / arch / powerpc / mm / pgtable_64.c
index cdf2123d46db4813a4e87f30d29f8da359c313d9..603db71ff21d3b81cc2be90c26b8955b3735c7f0 100644 (file)
@@ -88,7 +88,7 @@ static __ref void *early_alloc_pgtable(unsigned long size)
  * map_kernel_page adds an entry to the ioremap page table
  * and adds an entry to the HPT, possibly bolting it
  */
-int map_kernel_page(unsigned long ea, unsigned long pa, int flags)
+int map_kernel_page(unsigned long ea, unsigned long pa, unsigned long flags)
 {
        pgd_t *pgdp;
        pud_t *pudp;
@@ -277,11 +277,20 @@ void __iomem * ioremap_prot(phys_addr_t addr, unsigned long size,
        void *caller = __builtin_return_address(0);
 
        /* writeable implies dirty for kernel addresses */
-       if (flags & _PAGE_RW)
+       if (flags & _PAGE_WRITE)
                flags |= _PAGE_DIRTY;
 
-       /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
-       flags &= ~(_PAGE_USER | _PAGE_EXEC);
+       /* we don't want to let _PAGE_EXEC leak out */
+       flags &= ~_PAGE_EXEC;
+       /*
+        * Force kernel mapping.
+        */
+#if defined(CONFIG_PPC_BOOK3S_64)
+       flags |= _PAGE_PRIVILEGED;
+#else
+       flags &= ~_PAGE_USER;
+#endif
+
 
 #ifdef _PAGE_BAP_SR
        /* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format
@@ -403,7 +412,7 @@ static pte_t *__alloc_for_cache(struct mm_struct *mm, int kernel)
         * count.
         */
        if (likely(!mm->context.pte_frag)) {
-               atomic_set(&page->_count, PTE_FRAG_NR);
+               set_page_count(page, PTE_FRAG_NR);
                mm->context.pte_frag = ret + PTE_FRAG_SIZE;
        }
        spin_unlock(&mm->page_table_lock);
@@ -515,29 +524,29 @@ unsigned long pmd_hugepage_update(struct mm_struct *mm, unsigned long addr,
                                  unsigned long set)
 {
 
-       unsigned long old, tmp;
+       __be64 old_be, tmp;
+       unsigned long old;
 
 #ifdef CONFIG_DEBUG_VM
        WARN_ON(!pmd_trans_huge(*pmdp));
        assert_spin_locked(&mm->page_table_lock);
 #endif
 
-#ifdef PTE_ATOMIC_UPDATES
        __asm__ __volatile__(
        "1:     ldarx   %0,0,%3\n\
-               andi.   %1,%0,%6\n\
+               and   %1,%0,%6\n\
                bne-    1b \n\
                andc    %1,%0,%4 \n\
                or      %1,%1,%7\n\
                stdcx.  %1,0,%3 \n\
                bne-    1b"
-       : "=&r" (old), "=&r" (tmp), "=m" (*pmdp)
-       : "r" (pmdp), "r" (clr), "m" (*pmdp), "i" (_PAGE_BUSY), "r" (set)
+       : "=&r" (old_be), "=&r" (tmp), "=m" (*pmdp)
+       : "r" (pmdp), "r" (cpu_to_be64(clr)), "m" (*pmdp),
+         "r" (cpu_to_be64(_PAGE_BUSY)), "r" (cpu_to_be64(set))
        : "cc" );
-#else
-       old = pmd_val(*pmdp);
-       *pmdp = __pmd((old & ~clr) | set);
-#endif
+
+       old = be64_to_cpu(old_be);
+
        trace_hugepage_update(addr, old, clr, set);
        if (old & _PAGE_HASHPTE)
                hpte_do_hugepage_flush(mm, addr, pmdp, old);
@@ -664,7 +673,7 @@ void pmdp_huge_split_prepare(struct vm_area_struct *vma,
         * the translation is still valid, because we will withdraw
         * pgtable_t after this.
         */
-       pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_USER, 0);
+       pmd_hugepage_update(vma->vm_mm, address, pmdp, 0, _PAGE_PRIVILEGED);
 }
 
 
@@ -676,8 +685,7 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
                pmd_t *pmdp, pmd_t pmd)
 {
 #ifdef CONFIG_DEBUG_VM
-       WARN_ON((pmd_val(*pmdp) & (_PAGE_PRESENT | _PAGE_USER)) ==
-               (_PAGE_PRESENT | _PAGE_USER));
+       WARN_ON(pte_present(pmd_pte(*pmdp)) && !pte_protnone(pmd_pte(*pmdp)));
        assert_spin_locked(&mm->page_table_lock);
        WARN_ON(!pmd_trans_huge(pmd));
 #endif
@@ -749,7 +757,7 @@ pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
 {
        unsigned long pmdv;
 
-       pmdv = pfn << PTE_RPN_SHIFT;
+       pmdv = (pfn << PTE_RPN_SHIFT) & PTE_RPN_MASK;
        return pmd_set_protbits(__pmd(pmdv), pgprot);
 }
 
@@ -817,6 +825,13 @@ pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 
 int has_transparent_hugepage(void)
 {
+
+       BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) >= MAX_ORDER,
+               "hugepages can't be allocated by the buddy allocator");
+
+       BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) < 2,
+                        "We need more than 2 pages to do deferred thp split");
+
        if (!mmu_has_feature(MMU_FTR_16M_PAGE))
                return 0;
        /*