Skip to content

Commit f295070

Browse files
stevecapperlinaroRussell King
authored andcommitted
ARM: 8108/1: mm: Introduce {pte,pmd}_isset and {pte,pmd}_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. The logical inverse pte_isclear is also introduced. Equivalent pmd functions for Transparent HugePages have also been added. Signed-off-by: Steve Capper <[email protected]> Reviewed-by: Will Deacon <[email protected]> Signed-off-by: Russell King <[email protected]>
1 parent ddd0c53 commit f295070

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

arch/arm/include/asm/pgtable-3level.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,21 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
207207
#define pte_huge(pte) (pte_val(pte) && !(pte_val(pte) & PTE_TABLE_BIT))
208208
#define pte_mkhuge(pte) (__pte(pte_val(pte) & ~PTE_TABLE_BIT))
209209

210-
#define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF)
210+
#define pmd_isset(pmd, val) ((u32)(val) == (val) ? pmd_val(pmd) & (val) \
211+
: !!(pmd_val(pmd) & (val)))
212+
#define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val)))
213+
214+
#define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF))
211215

212216
#define __HAVE_ARCH_PMD_WRITE
213-
#define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY))
217+
#define pmd_write(pmd) (pmd_isclear((pmd), PMD_SECT_RDONLY))
214218

215219
#define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd))
216220
#define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd))
217221

218222
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
219-
#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
220-
#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
223+
#define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd))
224+
#define pmd_trans_splitting(pmd) (pmd_isset((pmd), PMD_SECT_SPLITTING))
221225
#endif
222226

223227
#define PMD_BIT_FUNC(fn,op) \

arch/arm/include/asm/pgtable.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,18 +214,22 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
214214

215215
#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
216216

217+
#define pte_isset(pte, val) ((u32)(val) == (val) ? pte_val(pte) & (val) \
218+
: !!(pte_val(pte) & (val)))
219+
#define pte_isclear(pte, val) (!(pte_val(pte) & (val)))
220+
217221
#define pte_none(pte) (!pte_val(pte))
218-
#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
219-
#define pte_valid(pte) (pte_val(pte) & L_PTE_VALID)
222+
#define pte_present(pte) (pte_isset((pte), L_PTE_PRESENT))
223+
#define pte_valid(pte) (pte_isset((pte), L_PTE_VALID))
220224
#define pte_accessible(mm, pte) (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte))
221-
#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
222-
#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
223-
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
224-
#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
225+
#define pte_write(pte) (pte_isclear((pte), L_PTE_RDONLY))
226+
#define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY))
227+
#define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG))
228+
#define pte_exec(pte) (pte_isclear((pte), L_PTE_XN))
225229
#define pte_special(pte) (0)
226230

227231
#define pte_valid_user(pte) \
228-
(pte_valid(pte) && (pte_val(pte) & L_PTE_USER) && pte_young(pte))
232+
(pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte))
229233

230234
#if __LINUX_ARM_ARCH__ < 6
231235
static inline void __sync_icache_dcache(pte_t pteval)

0 commit comments

Comments
 (0)