Merge remote-tracking branch 'origin/dev/sumit-linux-3.10.96' into TOT-merge
[linux-3.10.git] / arch / arm / include / asm / pgtable-3level.h
index 26c0dc4..60cd9cb 100644 (file)
@@ -33,7 +33,7 @@
 #define PTRS_PER_PMD           512
 #define PTRS_PER_PGD           4
 
-#define PTE_HWTABLE_PTRS       (PTRS_PER_PTE)
+#define PTE_HWTABLE_PTRS       (0)
 #define PTE_HWTABLE_OFF                (0)
 #define PTE_HWTABLE_SIZE       (PTRS_PER_PTE * sizeof(u64))
 
 #define PMD_SHIFT              21
 
 #define PMD_SIZE               (1UL << PMD_SHIFT)
-#define PMD_MASK               (~(PMD_SIZE-1))
+#define PMD_MASK               (~((1 << PMD_SHIFT) - 1))
 #define PGDIR_SIZE             (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK             (~(PGDIR_SIZE-1))
+#define PGDIR_MASK             (~((1 << PGDIR_SHIFT) - 1))
 
 /*
  * section address mask and size definitions.
  */
 #define SECTION_SHIFT          21
 #define SECTION_SIZE           (1UL << SECTION_SHIFT)
-#define SECTION_MASK           (~(SECTION_SIZE-1))
+#define SECTION_MASK           (~((1 << SECTION_SHIFT) - 1))
 
 #define USER_PTRS_PER_PGD      (PAGE_OFFSET / PGDIR_SIZE)
 
 #define L_PTE_PRESENT          (_AT(pteval_t, 3) << 0)         /* Present */
 #define L_PTE_FILE             (_AT(pteval_t, 1) << 2)         /* only when !PRESENT */
 #define L_PTE_USER             (_AT(pteval_t, 1) << 6)         /* AP[1] */
-#define L_PTE_RDONLY           (_AT(pteval_t, 1) << 7)         /* AP[2] */
 #define L_PTE_SHARED           (_AT(pteval_t, 3) << 8)         /* SH[1:0], inner shareable */
 #define L_PTE_YOUNG            (_AT(pteval_t, 1) << 10)        /* AF */
 #define L_PTE_XN               (_AT(pteval_t, 1) << 54)        /* XN */
-#define L_PTE_DIRTY            (_AT(pteval_t, 1) << 55)        /* unused */
-#define L_PTE_SPECIAL          (_AT(pteval_t, 1) << 56)        /* unused */
+#define L_PTE_DIRTY            (_AT(pteval_t, 1) << 55)
+#define L_PTE_SPECIAL          (_AT(pteval_t, 1) << 56)
 #define L_PTE_NONE             (_AT(pteval_t, 1) << 57)        /* PROT_NONE */
+#define L_PTE_RDONLY           (_AT(pteval_t, 1) << 58)        /* READ ONLY */
 
 #define PMD_SECT_VALID         (_AT(pmdval_t, 1) << 0)
 #define PMD_SECT_DIRTY         (_AT(pmdval_t, 1) << 55)
@@ -172,6 +172,23 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
                clean_pmd_entry(pmdp);  \
        } while (0)
 
+/*
+ * For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes
+ * that are written to a page table but not for ptes created with mk_pte.
+ *
+ * In hugetlb_no_page, a new huge pte (new_pte) is generated and passed to
+ * hugetlb_cow, where it is compared with an entry in a page table.
+ * This comparison test fails erroneously leading ultimately to a memory leak.
+ *
+ * To correct this behaviour, we mask off PTE_EXT_NG for any pte that is
+ * present before running the comparison.
+ */
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(pte_a,pte_b)  ((pte_present(pte_a) ? pte_val(pte_a) & ~PTE_EXT_NG     \
+                                       : pte_val(pte_a))                               \
+                               == (pte_present(pte_b) ? pte_val(pte_b) & ~PTE_EXT_NG   \
+                                       : pte_val(pte_b)))
+
 #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext)))
 
 #define pte_huge(pte)          (pte_val(pte) && !(pte_val(pte) & PTE_TABLE_BIT))