From: Ma Wupeng <mawupeng1@huawei.com> hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/9826 -------------------------------- Update kernel pte entries if pbha bit0 enabled. This can be used as a hit for kernel page entry for MMU. Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> Signed-off-by: Fanhua Li <lifanhua5@huawei.com> Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com> --- arch/arm64/include/asm/pgtable-hwdef.h | 1 + arch/arm64/mm/fixmap.c | 2 ++ arch/arm64/mm/mmu.c | 13 ++++++++++++- include/linux/pbha.h | 13 ++++++++++++- mm/vmalloc.c | 4 ++++ 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index 6b2e95af2971..25b4a70ae8e2 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -158,6 +158,7 @@ #define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ #define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ #define PTE_PBHA_MASK (_AT(pteval_t, 0xf) << 59) /* Page Base Hardware Attributes */ +#define PTE_PBHA0 (_AT(pteval_t, 1) << 59) /* PBHA 59 bit */ #define PTE_ADDR_LOW (((_AT(pteval_t, 1) << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT) #ifdef CONFIG_ARM64_PA_BITS_52 diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c index a55b36d04590..9bb565f1cc20 100644 --- a/arch/arm64/mm/fixmap.c +++ b/arch/arm64/mm/fixmap.c @@ -10,6 +10,7 @@ #include <linux/memory.h> #include <linux/mm.h> #include <linux/sizes.h> +#include <linux/pbha.h> #include <asm/fixmap.h> #include <asm/kernel-pgtable.h> @@ -124,6 +125,7 @@ void __set_fixmap(enum fixed_addresses idx, ptep = fixmap_pte(addr); if (pgprot_val(flags)) { + flags = pgprot_pbha_bit0(flags); __set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); } else { __pte_clear(&init_mm, addr, ptep); diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 6ffd7305ee80..47da7fb76903 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -27,6 +27,7 @@ #include <linux/kfence.h> #include <linux/pagewalk.h> #include <linux/stop_machine.h> +#include <linux/pbha.h> #include <linux/numa_remote.h> #include "internal.h" @@ -151,6 +152,10 @@ bool pgattr_change_is_safe(u64 old, u64 new) */ pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG; +#ifdef CONFIG_ARM64_PBHA + mask |= PTE_PBHA0; +#endif + /* creating or taking down mappings is always safe */ if (!pte_valid(__pte(old)) || !pte_valid(__pte(new))) return true; @@ -395,6 +400,8 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) return; + prot = pgprot_pbha_bit0(prot); + phys &= PAGE_MASK; addr = virt & PAGE_MASK; end = PAGE_ALIGN(virt + size); @@ -1630,7 +1637,11 @@ void __init pmd_mapping_reserved_remap(phys_addr_t start, phys_addr_t end) void __meminit vmemmap_set_pmd(pmd_t *pmdp, void *p, int node, unsigned long addr, unsigned long next) { - pmd_set_huge(pmdp, __pa(p), __pgprot(PROT_SECT_NORMAL)); + pgprot_t prot; + + prot = __pgprot(PROT_SECT_NORMAL); + prot = pgprot_pbha_bit0(prot); + pmd_set_huge(pmdp, __pa(p), prot); } int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node, diff --git a/include/linux/pbha.h b/include/linux/pbha.h index 87cfda8041bf..35af1571091d 100644 --- a/include/linux/pbha.h +++ b/include/linux/pbha.h @@ -5,8 +5,10 @@ #ifndef __LINUX_PBHA_H #define __LINUX_PBHA_H -#include <linux/efi.h> #include <linux/libfdt.h> +#include <linux/pgtable.h> + +#define PBHA_VAL_BIT0 1UL #define EFI_OEMCONFIG_VARIABLE_GUID \ EFI_GUID(0x21f3b3c5, 0x946d, 0x41c1, 0x83, 0x8c, 0x19, 0x4e, 0x48, \ @@ -23,8 +25,17 @@ static inline bool system_support_pbha_bit0(void) { return pbha_bit0_enabled; } + +static inline pgprot_t pgprot_pbha_bit0(pgprot_t prot) +{ + if (!system_support_pbha_bit0()) + return prot; + + return pgprot_pbha(prot, PBHA_VAL_BIT0); +} #else static inline bool system_support_pbha_bit0(void) { return false; } +static inline pgprot_t pgprot_pbha_bit0(pgprot_t prot) { return prot; } #endif #endif diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 80f91878d150..455287090795 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -40,6 +40,7 @@ #include <linux/pgtable.h> #include <linux/hugetlb.h> #include <linux/sched/mm.h> +#include <linux/pbha.h> #include <asm/tlbflush.h> #include <asm/shmparam.h> #include <linux/cleanup.h> @@ -340,6 +341,7 @@ int vmap_page_range(unsigned long addr, unsigned long end, { int err; + prot = pgprot_pbha_bit0(prot); err = vmap_range_noflush(addr, end, phys_addr, pgprot_nx(prot), ioremap_max_page_shift); flush_cache_vmap(addr, end); @@ -642,6 +644,8 @@ int __vmap_pages_range_noflush(unsigned long addr, unsigned long end, WARN_ON(page_shift < PAGE_SHIFT); + prot = pgprot_pbha_bit0(prot); + if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMALLOC) || page_shift == PAGE_SHIFT) return vmap_small_pages_range_noflush(addr, end, prot, pages); -- 2.43.0