Commit 61bcbaac authored by Yicong Yang's avatar Yicong Yang Committed by JangShui Yang
Browse files

arm64: Add support for FEAT_HAFT

mainline inclusion
from mainline-v6.13-rc1
commit efe72541355d4d40a4f076af453f6533e98e058c
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IB4YD4
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=efe72541355d4d40a4f076af453f6533e98e058c



----------------------------------------------------------------------

Armv8.9/v9.4 introduces the feature Hardware managed Access Flag
for Table descriptors (FEAT_HAFT). The feature is indicated by
ID_AA64MMFR1_EL1.HAFDBS == 0b0011 and can be enabled by
TCR2_EL1.HAFT so it has a dependency on FEAT_TCR2.

Adds the Kconfig for FEAT_HAFT and support detecting and enabling
the feature. The feature is enabled in __cpu_setup() before MMU on
just like HA. A CPU capability is added to notify the user of the
feature.

Add definition of P{G,4,U,M}D_TABLE_AF bit and set the AF bit
when creating the page table, which will save the hardware
from having to update them at runtime. This will be ignored if
FEAT_HAFT is not enabled.

The AF bit of table descriptors cannot be managed by the software
per spec, unlike the HA. So this should be used only if it's supported
system wide by system_supports_haft().

Signed-off-by: default avatarYicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/20241102104235.62560-4-yangyicong@huawei.com


Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
[catalin.marinas@arm.com: added the ID check back to __cpu_setup in case of future CPU errata]
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Conflicts:
	arch/arm64/Kconfig
	arch/arm64/include/asm/cpufeature.h
	arch/arm64/kernel/cpufeature.c
	arch/arm64/mm/mmu.c
	arch/arm64/tools/cpucaps
[Context conflicts]
Signed-off-by: default avatarJiangShui Yang <yangjiangshui@h-partners.com>
parent db8b549b
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -2309,6 +2309,21 @@ config ARM64_NMI
	  if the cpu does not implement the feature. It will also be
	  disabled if pseudo NMIs are enabled at runtime.

config ARM64_HAFT
	bool "Support for Hardware managed Access Flag for Table Descriptors"
	depends on ARM64_HW_AFDBM
	default y
	help
	  The ARMv8.9/ARMv9.5 introduces the feature Hardware managed Access
	  Flag for Table descriptors. When enabled an architectural executed
	  memory access will update the Access Flag in each Table descriptor
	  which is accessed during the translation table walk and for which
	  the Access Flag is 0. The Access Flag of the Table descriptor use
	  the same bit of PTE_AF.

	  The feature will only be enabled if all the CPUs in the system
	  support this feature. If unsure, say Y.

endmenu # "ARMv8.8 architectural features"

config ARM64_SVE
+6 −0
Original line number Diff line number Diff line
@@ -860,6 +860,12 @@ static inline bool cpus_support_mpam(void)

bool mpam_detect_is_enabled(void);

static inline bool system_supports_haft(void)
{
	return IS_ENABLED(CONFIG_ARM64_HAFT) &&
		cpus_have_final_cap(ARM64_HAFT);
}

int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);

+6 −4
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)

static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
{
	pudval_t pudval = PUD_TYPE_TABLE;
	pudval_t pudval = PUD_TYPE_TABLE | PUD_TABLE_AF;

	pudval |= (mm == &init_mm) ? PUD_TABLE_UXN : PUD_TABLE_PXN;
	__pud_populate(pudp, __pa(pmdp), pudval);
@@ -48,7 +48,7 @@ static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)

static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
{
	p4dval_t p4dval = P4D_TYPE_TABLE;
	p4dval_t p4dval = P4D_TYPE_TABLE | P4D_TABLE_AF;

	p4dval |= (mm == &init_mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
	__p4d_populate(p4dp, __pa(pudp), p4dval);
@@ -77,14 +77,16 @@ static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
{
	VM_BUG_ON(mm && mm != &init_mm);
	__pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE | PMD_TABLE_UXN);
	__pmd_populate(pmdp, __pa(ptep),
		       PMD_TYPE_TABLE | PMD_TABLE_AF | PMD_TABLE_UXN);
}

static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
{
	VM_BUG_ON(mm == &init_mm);
	__pmd_populate(pmdp, page_to_phys(ptep), PMD_TYPE_TABLE | PMD_TABLE_PXN);
	__pmd_populate(pmdp, page_to_phys(ptep),
		       PMD_TYPE_TABLE | PMD_TABLE_AF | PMD_TABLE_PXN);
}

#endif
+3 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@
#define P4D_TYPE_MASK		(_AT(p4dval_t, 3) << 0)
#define P4D_TYPE_SECT		(_AT(p4dval_t, 1) << 0)
#define P4D_SECT_RDONLY		(_AT(p4dval_t, 1) << 7)		/* AP[2] */
#define P4D_TABLE_AF		(_AT(p4dval_t, 1) << 10)	/* Ignored if no FEAT_HAFT */
#define P4D_TABLE_PXN		(_AT(p4dval_t, 1) << 59)
#define P4D_TABLE_UXN		(_AT(p4dval_t, 1) << 60)

@@ -105,6 +106,7 @@
#define PUD_TYPE_MASK		(_AT(pudval_t, 3) << 0)
#define PUD_TYPE_SECT		(_AT(pudval_t, 1) << 0)
#define PUD_SECT_RDONLY		(_AT(pudval_t, 1) << 7)		/* AP[2] */
#define PUD_TABLE_AF		(_AT(pudval_t, 1) << 10)	/* Ignored if no FEAT_HAFT */
#define PUD_TABLE_PXN		(_AT(pudval_t, 1) << 59)
#define PUD_TABLE_UXN		(_AT(pudval_t, 1) << 60)

@@ -115,6 +117,7 @@
#define PMD_TYPE_TABLE		(_AT(pmdval_t, 3) << 0)
#define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)
#define PMD_TABLE_BIT		(_AT(pmdval_t, 1) << 1)
#define PMD_TABLE_AF		(_AT(pmdval_t, 1) << 10)	/* Ignored if no FEAT_HAFT */

/*
 * Section
+15 −0
Original line number Diff line number Diff line
@@ -2598,6 +2598,21 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
		.cpu_enable = cpu_enable_hw_dbm,
		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, DBM)
	},
#endif
#ifdef CONFIG_ARM64_HAFT
	{
		.desc = "Hardware managed Access Flag for Table Descriptors",
		/*
		 * Contrary to the page/block access flag, the table access flag
		 * cannot be emulated in software (no access fault will occur).
		 * Therefore this should be used only if it's supported system
		 * wide.
		 */
		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
		.capability = ARM64_HAFT,
		.matches = has_cpuid_feature,
		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, HAFT)
	},
#endif
	{
		.desc = "CRC32 instructions",
Loading