aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Capper <steve.capper@linaro.org>2014-03-28 14:22:33 +0000
committerAnders Roxell <anders.roxell@linaro.org>2014-05-19 15:06:28 +0200
commit3028bfaafebd65f67c027e094fa24fc9db727c40 (patch)
tree76eed7eddb67261ac44008803e83bdf971859406
parentc7cdb7b079738b0b29b244ce33cc3369f7129d4e (diff)
arm: mm: Introduce pte_isset and pte_isclear
Long descriptors on ARM are 64 bits, and some pte functions such as pte_dirty return a bitwise-and of a flag with the pte value. If the flag to be tested resides in the upper 32 bits of the pte, then we run into the danger of the result being dropped if downcast. For example: gather_stats(page, md, pte_dirty(*pte), 1); where pte_dirty(*pte) is downcast to an int. This patch introduces a new macro pte_isset which performs the bitwise and, then performs a double logical invert (where needed) to ensure predictable downcasting. Signed-off-by: Steve Capper <steve.capper@linaro.org>
-rw-r--r--arch/arm/include/asm/pgtable.h18
1 files changed, 11 insertions, 7 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 3675c63dac46..bc9225010c87 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -212,16 +212,20 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
+#define pte_isset(pte, val) ((u32)(val) == (val) ? pte_val(pte) & (val) \
+ : !!(pte_val(pte) & (val)))
+#define pte_isclear(pte, val) (!(pte_val(pte) & (val)))
+
#define pte_none(pte) (!pte_val(pte))
-#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
-#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
-#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
-#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
-#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
-#define pte_protnone(pte) (pte_val(pte) & L_PTE_NONE)
+#define pte_present(pte) (pte_isset((pte), L_PTE_PRESENT))
+#define pte_write(pte) (pte_isclear((pte), L_PTE_RDONLY))
+#define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY))
+#define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG))
+#define pte_exec(pte) (pte_isclear((pte), L_PTE_XN))
+#define pte_protnone(pte) (pte_isset((pte), L_PTE_NONE))
#define pte_special(pte) (0)
-#define pte_present_user(pte) (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
+#define pte_present_user(pte) (pte_present(pte) && pte_isset((pte), L_PTE_USER))
#if __LINUX_ARM_ARCH__ < 6
static inline void __sync_icache_dcache(unsigned long pfn, int exec);