From: Ma Wupeng mawupeng1@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I96IZH
--------------------------------
Bit 57 is used Commit fb8e37f35a2f ("mm/pagemap: export uffd-wp protection information"). Use bit 59 to improve future compatibility for pbha.
Signed-off-by: Ma Wupeng mawupeng1@huawei.com --- Documentation/admin-guide/mm/pagemap.rst | 4 +++- fs/proc/task_mmu.c | 15 +++++++++++++++ include/linux/pbha.h | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/mm/pagemap.rst b/Documentation/admin-guide/mm/pagemap.rst index 2f472dd3ee9f..bfaa9a2aeb67 100644 --- a/Documentation/admin-guide/mm/pagemap.rst +++ b/Documentation/admin-guide/mm/pagemap.rst @@ -21,7 +21,9 @@ There are four components to pagemap: * Bit 55 pte is soft-dirty (see :ref:`Documentation/admin-guide/mm/soft-dirty.rst <soft_dirty>`) * Bit 56 page exclusively mapped (since 4.2) - * Bits 57-60 zero + * Bits 57-58 zero + * Bit 59 PBHA bit0, used only CONFIG_ARM64_PBHA is enabled + * Bits 60 zero * Bit 61 page is file-page or shared-anon (since 3.5) * Bit 62 page swapped * Bit 63 page present diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index d54e0e3474cc..e20e97fa9d1e 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -20,6 +20,7 @@ #include <linux/uaccess.h> #include <linux/pkeys.h> #include <linux/module.h> +#include <linux/pbha.h>
#include <asm/elf.h> #include <asm/tlb.h> @@ -1327,6 +1328,11 @@ struct pagemapread { #define PM_PFRAME_MASK GENMASK_ULL(PM_PFRAME_BITS - 1, 0) #define PM_SOFT_DIRTY BIT_ULL(55) #define PM_MMAP_EXCLUSIVE BIT_ULL(56) +#ifdef CONFIG_ARM64_PBHA +#define PM_PBHA_BIT0 BIT_ULL(59) +#else +#define PM_PBHA_BIT0 BIT_ULL(0) +#endif #define PM_FILE BIT_ULL(61) #define PM_SWAP BIT_ULL(62) #define PM_PRESENT BIT_ULL(63) @@ -1419,6 +1425,9 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm, page = device_private_entry_to_page(entry); }
+ if (pte_pbha(pte)) + flags |= PM_PBHA_BIT0; + if (page && !PageAnon(page)) flags |= PM_FILE; if (page && !migration && page_mapcount(page) == 1) @@ -1479,6 +1488,9 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, } #endif
+ if (pmd_pbha(pmd)) + flags |= PM_PBHA_BIT0; + if (page && !migration && page_mapcount(page) == 1) flags |= PM_MMAP_EXCLUSIVE;
@@ -1711,6 +1723,9 @@ static int get_pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long pmd_t pmd = *pmdp; struct page *page = NULL;
+ if (pmd_pbha(pmd)) + flags |= PM_PBHA_BIT0; + if (pmd_present(pmd)) { page = pmd_page(pmd); flags |= PM_PRESENT; diff --git a/include/linux/pbha.h b/include/linux/pbha.h index 25cb88aa3d1c..123f5c8df3e0 100644 --- a/include/linux/pbha.h +++ b/include/linux/pbha.h @@ -54,6 +54,16 @@ static inline pte_t maybe_mk_pbha_bit0(pte_t pte, struct vm_area_struct *vma)
return pte; } + +static inline bool pte_pbha(pte_t pte) +{ + return !!(pte_val(pte) & (PBHA_VAL_BIT0 << PBHA_BITS_SHIFT)); +} + +static inline bool pmd_pbha(pmd_t pmd) +{ + return !!(pmd_val(pmd) & (PBHA_VAL_BIT0 << PBHA_BITS_SHIFT)); +} #else static inline bool system_support_pbha_bit0(void) { return false; } static inline pgprot_t pgprot_pbha_bit0(pgprot_t prot) { return prot; } @@ -61,6 +71,14 @@ static inline pte_t maybe_mk_pbha_bit0(pte_t pte, struct vm_area_struct *vma) { return pte; } +static inline bool pte_pbha(pte_t pte) +{ + return false; +} +static inline bool pmd_pbha(pmd_t pte) +{ + return false; +} #endif
#endif