diff --git a/Documentation/admin-guide/mm/pagemap.rst b/Documentation/admin-guide/mm/pagemap.rst index 2f472dd3ee9fc6617476e3d1d7e24e8c51586a73..bfaa9a2aeb67fc1969aaa921e6fe67bf8bc90a6a 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 `) * 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/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index eafaeb54f80850dc7dc134fe3167cb88054096e6..5ad5e4378f2f8926adb3593185e8d81a8655382c 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -497,7 +497,7 @@ CONFIG_ARM64_VHE=y CONFIG_ARM64_PMEM=y CONFIG_ARM64_RAS_EXTN=y CONFIG_ARM64_CNP=y -# CONFIG_ARM64_PBHA is not set +CONFIG_ARM64_PBHA=y # end of ARMv8.2 architectural features # diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 5aabbbc74f281cdee33a42369d32d9da05c6db76..9a4193991be5a23657779462b93ab6c6bbe86f06 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1687,7 +1687,7 @@ static void stage2_test_pbha_value(u8 val) arm64_pbha_stage2_safe_bits |= val; } -void update_pbha_perf_only_bit(const u8 *bits, int cnt) +static void update_pbha_perf_only_bit(const u8 *bits, int cnt) { u8 val; int i; diff --git a/drivers/soc/hisilicon/pbha.c b/drivers/soc/hisilicon/pbha.c index 30d5057d8f9534f01d990309b32cc60b5250f3f0..57daa5c338b52ab0323d34a17a2025c375e6bd3d 100644 --- a/drivers/soc/hisilicon/pbha.c +++ b/drivers/soc/hisilicon/pbha.c @@ -99,7 +99,7 @@ static int pbha_bit0_pte_range(pmd_t *pmd, unsigned long addr, { int *op = (int *)walk->private; struct vm_area_struct *vma = walk->vma; - pte_t *pte, ptent; + pte_t *pte; spinlock_t *ptl; bool set = (*op == SET_PBHA_BIT0_FLAG); @@ -115,11 +115,8 @@ static int pbha_bit0_pte_range(pmd_t *pmd, unsigned long addr, return 0; pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); - for (; addr != end; pte++, addr += PAGE_SIZE) { - ptent = *pte; - + for (; addr != end; pte++, addr += PAGE_SIZE) pbha_bit0_update_pte_bits(vma, addr, pte, set); - } pte_unmap_unlock(pte - 1, ptl); cond_resched(); return 0; @@ -200,7 +197,9 @@ static int __init setup_pbha(char *str) pbha_bit0_enabled = true; } - pr_info("pbha bit_0 enabled, kernel: %d\n", pbha_bit0_kernel_enabled); + if (pbha_bit0_enabled) + pr_info("pbha bit_0 enabled, kernel: %d\n", + pbha_bit0_kernel_enabled); return 0; } diff --git a/fs/proc/base.c b/fs/proc/base.c index 88842619f830ba0c762efdc8863a4b94e5fe2d06..4e0054a37c4c54fa808264b1130ff2074d292bad 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1450,6 +1450,16 @@ static const struct file_operations proc_pbha_bit0_ops = { .write = pbha_bit0_write, .llseek = generic_file_llseek, }; + +bool pbha_bit0_hide_file(const char *name) +{ + if (!system_support_pbha_bit0() && !strncmp("pbha_bit0", name, 9)) + return true; + + return false; +} +#else +static bool pbha_bit0_hide_file(const char *name) { return false; } #endif #ifdef CONFIG_AUDIT @@ -2847,6 +2857,14 @@ static struct dentry *proc_pident_instantiate(struct dentry *dentry, return d_splice_alias(inode, dentry); } +static bool proc_hide_pidents(const struct pid_entry *p) +{ + if (pbha_bit0_hide_file(p->name)) + return true; + + return false; +} + static struct dentry *proc_pident_lookup(struct inode *dir, struct dentry *dentry, const struct pid_entry *p, @@ -2865,6 +2883,8 @@ static struct dentry *proc_pident_lookup(struct inode *dir, for (; p < end; p++) { if (p->len != dentry->d_name.len) continue; + if (proc_hide_pidents(p)) + continue; if (!memcmp(dentry->d_name.name, p->name, p->len)) { res = proc_pident_instantiate(dentry, task, p); break; @@ -2891,8 +2911,9 @@ static int proc_pident_readdir(struct file *file, struct dir_context *ctx, goto out; for (p = ents + (ctx->pos - 2); p < ents + nents; p++) { - if (!proc_fill_cache(file, ctx, p->name, p->len, - proc_pident_instantiate, task, p)) + if (!proc_hide_pidents(p) && + !proc_fill_cache(file, ctx, p->name, p->len, + proc_pident_instantiate, task, p)) break; ctx->pos++; } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index d54e0e3474cc5ade169071c498bba58e3f9a7609..decf5e287b7ee78186be7bcf2c3c27c2ae39e301 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -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 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 25cb88aa3d1c3a33c8c36ec675359ed8b4649856..45a4b07778bfa02047011cde82497d6b6c3e509a 100644 --- a/include/linux/pbha.h +++ b/include/linux/pbha.h @@ -54,6 +54,22 @@ 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) +{ + if (!system_support_pbha_bit0()) + return false; + + return !!(pte_val(pte) & (PBHA_VAL_BIT0 << PBHA_BITS_SHIFT)); +} + +static inline bool pmd_pbha(pmd_t pmd) +{ + if (!system_support_pbha_bit0()) + return false; + + 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 +77,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