diff mbox series

[1/2] arm64: Add support for FEAT_HAFT

Message ID 20240802093458.32683-2-yangyicong@huawei.com (mailing list archive)
State New, archived
Headers show
Series Support Armv8.9/v9.4 FEAT_HAFT | expand

Commit Message

Yicong Yang Aug. 2, 2024, 9:34 a.m. UTC
From: Yicong Yang <yangyicong@hisilicon.com>

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.

This patch adds the Kconfig for FEAT_HAFT and support detecting
and enabling the feature.

Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
---
 arch/arm64/Kconfig                     | 20 ++++++++++++++
 arch/arm64/include/asm/pgtable-hwdef.h |  5 ++++
 arch/arm64/kernel/cpufeature.c         | 38 ++++++++++++++++++++++++++
 arch/arm64/tools/cpucaps               |  1 +
 arch/arm64/tools/sysreg                |  1 +
 5 files changed, 65 insertions(+)

Comments

Marc Zyngier Aug. 2, 2024, 10:37 a.m. UTC | #1
On Fri, 02 Aug 2024 10:34:57 +0100,
Yicong Yang <yangyicong@huawei.com> wrote:
> 
> From: Yicong Yang <yangyicong@hisilicon.com>
> 
> 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.
> 
> This patch adds the Kconfig for FEAT_HAFT and support detecting
> and enabling the feature.
> 
> Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
> ---
>  arch/arm64/Kconfig                     | 20 ++++++++++++++
>  arch/arm64/include/asm/pgtable-hwdef.h |  5 ++++
>  arch/arm64/kernel/cpufeature.c         | 38 ++++++++++++++++++++++++++
>  arch/arm64/tools/cpucaps               |  1 +
>  arch/arm64/tools/sysreg                |  1 +
>  5 files changed, 65 insertions(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b3fc891f1544..f263ae4139a5 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -2127,6 +2127,26 @@ config ARM64_EPAN
>  	  if the cpu does not implement the feature.
>  endmenu # "ARMv8.7 architectural features"
>  
> +menu "ARMv8.9 architectural features"
> +
> +config ARM64_HAFT
> +	bool "Support for Hardware managed Access Flag for Table Descriptor"
> +	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 in TCR_EL1 (HAFT bit) on

TCR2_EL{1,2}. But I don't think we need to details registers and bit
layout in the help section.

> +	  capable processors, 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 on supported CPUs. If unsure,
> +	  say Y.
> +
> +endmenu # "ARMv8.9 architectural features"
> +
>  config ARM64_SVE
>  	bool "ARM Scalable Vector Extension support"
>  	default y
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index 1f60aa1bc750..47bd29874e62 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -308,6 +308,11 @@
>  #define TCR_TCMA1		(UL(1) << 58)
>  #define TCR_DS			(UL(1) << 59)
>  
> +/*
> + * TCR2 Flags
> + */
> +#define TCR2_HAFT		(UL(1) << 11)
> +

TCR2_ELx is already fully described in arch/arm64/tools/sysreg.

>  /*
>   * TTBR.
>   */
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 646ecd3069fd..99402fd00f16 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2044,6 +2044,29 @@ static bool has_hw_dbm(const struct arm64_cpu_capabilities *cap,
>  
>  #endif
>  
> +#if CONFIG_ARM64_HAFT
> +
> +static void cpu_enable_haft(struct arm64_cpu_capabilities const *cap)
> +{
> +	u64 reg = read_sysreg_s(SYS_TCR2_EL1);
> +
> +	reg |= TCR2_HAFT;
> +	write_sysreg_s(reg, SYS_TCR2_EL1);

Probably more elegantly written as

	sysreg_clear_set_s(SYS_TCR2_EL1, 0, TCR2_EL1x_HAFT);

> +	isb();
> +	local_flush_tlb_all();
> +}
> +
> +static bool has_haft(const struct arm64_cpu_capabilities *cap, int scope)
> +{
> +	/* FEAT_HAFT relies on FEAT_TCR2 */
> +	if (!this_cpu_has_cap(ARM64_HAS_TCR2))
> +		return false;

Why do we need this? If FEAT_TCR2 isn't implemented, this is a HW bug.

> +
> +	return has_cpuid_feature(cap, scope);
> +}
> +
> +#endif
> +
>  #ifdef CONFIG_ARM64_AMU_EXTN
>  
>  /*
> @@ -2580,6 +2603,21 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.cpus = &dbm_cpus,
>  		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, DBM)
>  	},
> +#endif
> +#ifdef CONFIG_ARM64_HAFT
> +	{
> +		.desc = "Hardware managed Access Flag for Table Descriptor",
> +		/*
> +		 * Per Spec, software management of Access Flag for Table
> +		 * descriptor is not supported, so make this feature system
> +		 * wide.
> +		 */

I don't understand what you mean by this. Can you please clarify?

> +		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
> +		.capability = ARM64_HAFT,
> +		.matches = has_haft,
> +		.cpu_enable = cpu_enable_haft,
> +		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, HAFT)
> +	},
>  #endif
>  	{
>  		.desc = "CRC32 instructions",
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index ac3429d892b9..0b7a3a237e5d 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -55,6 +55,7 @@ HAS_TLB_RANGE
>  HAS_VA52
>  HAS_VIRT_HOST_EXTN
>  HAS_WFXT
> +HAFT
>  HW_DBM
>  KVM_HVHE
>  KVM_PROTECTED_MODE
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 7ceaa1e0b4bc..9b3d15ea8a63 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -1688,6 +1688,7 @@ UnsignedEnum	3:0	HAFDBS
>  	0b0000	NI
>  	0b0001	AF
>  	0b0010	DBM
> +	0b0011	HAFT
>  EndEnum
>  EndSysreg
>  

Thanks,

	M.
Yicong Yang Aug. 6, 2024, 3:09 a.m. UTC | #2
Hi Marc,

Thanks for the comments.

On 2024/8/2 18:37, Marc Zyngier wrote:
> On Fri, 02 Aug 2024 10:34:57 +0100,
> Yicong Yang <yangyicong@huawei.com> wrote:
>>
>> From: Yicong Yang <yangyicong@hisilicon.com>
>>
>> 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.
>>
>> This patch adds the Kconfig for FEAT_HAFT and support detecting
>> and enabling the feature.
>>
>> Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
>> ---
>>  arch/arm64/Kconfig                     | 20 ++++++++++++++
>>  arch/arm64/include/asm/pgtable-hwdef.h |  5 ++++
>>  arch/arm64/kernel/cpufeature.c         | 38 ++++++++++++++++++++++++++
>>  arch/arm64/tools/cpucaps               |  1 +
>>  arch/arm64/tools/sysreg                |  1 +
>>  5 files changed, 65 insertions(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b3fc891f1544..f263ae4139a5 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -2127,6 +2127,26 @@ config ARM64_EPAN
>>  	  if the cpu does not implement the feature.
>>  endmenu # "ARMv8.7 architectural features"
>>  
>> +menu "ARMv8.9 architectural features"
>> +
>> +config ARM64_HAFT
>> +	bool "Support for Hardware managed Access Flag for Table Descriptor"
>> +	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 in TCR_EL1 (HAFT bit) on
> 
> TCR2_EL{1,2}. But I don't think we need to details registers and bit
> layout in the help section.
> 

ok. will drop this information.

>> +	  capable processors, 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 on supported CPUs. If unsure,
>> +	  say Y.
>> +
>> +endmenu # "ARMv8.9 architectural features"
>> +
>>  config ARM64_SVE
>>  	bool "ARM Scalable Vector Extension support"
>>  	default y
>> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
>> index 1f60aa1bc750..47bd29874e62 100644
>> --- a/arch/arm64/include/asm/pgtable-hwdef.h
>> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
>> @@ -308,6 +308,11 @@
>>  #define TCR_TCMA1		(UL(1) << 58)
>>  #define TCR_DS			(UL(1) << 59)
>>  
>> +/*
>> + * TCR2 Flags
>> + */
>> +#define TCR2_HAFT		(UL(1) << 11)
>> +
> 
> TCR2_ELx is already fully described in arch/arm64/tools/sysreg.
> 

ok. will use the definition generated by sysreg.

>>  /*
>>   * TTBR.
>>   */
>> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
>> index 646ecd3069fd..99402fd00f16 100644
>> --- a/arch/arm64/kernel/cpufeature.c
>> +++ b/arch/arm64/kernel/cpufeature.c
>> @@ -2044,6 +2044,29 @@ static bool has_hw_dbm(const struct arm64_cpu_capabilities *cap,
>>  
>>  #endif
>>  
>> +#if CONFIG_ARM64_HAFT
>> +
>> +static void cpu_enable_haft(struct arm64_cpu_capabilities const *cap)
>> +{
>> +	u64 reg = read_sysreg_s(SYS_TCR2_EL1);
>> +
>> +	reg |= TCR2_HAFT;
>> +	write_sysreg_s(reg, SYS_TCR2_EL1);
> 
> Probably more elegantly written as
> 
> 	sysreg_clear_set_s(SYS_TCR2_EL1, 0, TCR2_EL1x_HAFT);
> 

this is simpler. will use sysreg_clear_set_s().

>> +	isb();
>> +	local_flush_tlb_all();
>> +}
>> +
>> +static bool has_haft(const struct arm64_cpu_capabilities *cap, int scope)
>> +{
>> +	/* FEAT_HAFT relies on FEAT_TCR2 */
>> +	if (!this_cpu_has_cap(ARM64_HAS_TCR2))
>> +		return false;
> 
> Why do we need this? If FEAT_TCR2 isn't implemented, this is a HW bug.
> 

yes you're right. as spec mentioned:
If FEAT_HAFT is implemented, then FEAT_TCR2 is implemented.

So this check is redundant. We can simply use has_cpuid_feature() instead
without checking FEAT_TCR2 here.

>> +
>> +	return has_cpuid_feature(cap, scope);
>> +}
>> +
>> +#endif
>> +
>>  #ifdef CONFIG_ARM64_AMU_EXTN
>>  
>>  /*
>> @@ -2580,6 +2603,21 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>>  		.cpus = &dbm_cpus,
>>  		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, DBM)
>>  	},
>> +#endif
>> +#ifdef CONFIG_ARM64_HAFT
>> +	{
>> +		.desc = "Hardware managed Access Flag for Table Descriptor",
>> +		/*
>> +		 * Per Spec, software management of Access Flag for Table
>> +		 * descriptor is not supported, so make this feature system
>> +		 * wide.
>> +		 */
> 
> I don't understand what you mean by this. Can you please clarify?
> 

Since this cannot be managed by the software, we should restrict all the CPUs
in the system to have and enable this feature which is indicated by
ARM64_CPUCAP_BOOT_CPU_FEATURE. It's not possible for part of the CPUs don't have
this feature and managed manually.

I make this comment here since it's handled different from what ARM64_HW_DBM does (which
is ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE). Maybe it's redundant and can be dropped.

Thanks.

>> +		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
>> +		.capability = ARM64_HAFT,
>> +		.matches = has_haft,
>> +		.cpu_enable = cpu_enable_haft,
>> +		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, HAFT)
>> +	},
>>  #endif
>>  	{
>>  		.desc = "CRC32 instructions",
>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>> index ac3429d892b9..0b7a3a237e5d 100644
>> --- a/arch/arm64/tools/cpucaps
>> +++ b/arch/arm64/tools/cpucaps
>> @@ -55,6 +55,7 @@ HAS_TLB_RANGE
>>  HAS_VA52
>>  HAS_VIRT_HOST_EXTN
>>  HAS_WFXT
>> +HAFT
>>  HW_DBM
>>  KVM_HVHE
>>  KVM_PROTECTED_MODE
>> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
>> index 7ceaa1e0b4bc..9b3d15ea8a63 100644
>> --- a/arch/arm64/tools/sysreg
>> +++ b/arch/arm64/tools/sysreg
>> @@ -1688,6 +1688,7 @@ UnsignedEnum	3:0	HAFDBS
>>  	0b0000	NI
>>  	0b0001	AF
>>  	0b0010	DBM
>> +	0b0011	HAFT
>>  EndEnum
>>  EndSysreg
>>  
> 
> Thanks,
> 
> 	M.
>
Marc Zyngier Aug. 6, 2024, 7:57 a.m. UTC | #3
On Tue, 06 Aug 2024 04:09:09 +0100,
Yicong Yang <yangyicong@huawei.com> wrote:
> 
> >> +#ifdef CONFIG_ARM64_HAFT
> >> +	{
> >> +		.desc = "Hardware managed Access Flag for Table Descriptor",
> >> +		/*
> >> +		 * Per Spec, software management of Access Flag for Table
> >> +		 * descriptor is not supported, so make this feature system
> >> +		 * wide.
> >> +		 */
> > 
> > I don't understand what you mean by this. Can you please clarify?
> > 
> 
> Since this cannot be managed by the software, we should restrict all the CPUs
> in the system to have and enable this feature which is indicated by
> ARM64_CPUCAP_BOOT_CPU_FEATURE. It's not possible for part of the CPUs don't have
> this feature and managed manually.
> 
> I make this comment here since it's handled different from what ARM64_HW_DBM does (which
> is ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE). Maybe it's redundant and can be dropped.

Ah, I see what you mean. I think this is still important to capture,
but maybe in a clearer manner. Something like:

	Contrary to the page/block access flag, the table access flag
	cannot be emulated in software (no access fault will occur).
	Therefore mandate that all CPUs have FEAT_HAFT.

Thanks,

	M.
Yicong Yang Aug. 6, 2024, 1:11 p.m. UTC | #4
On 2024/8/6 15:57, Marc Zyngier wrote:
> On Tue, 06 Aug 2024 04:09:09 +0100,
> Yicong Yang <yangyicong@huawei.com> wrote:
>>
>>>> +#ifdef CONFIG_ARM64_HAFT
>>>> +	{
>>>> +		.desc = "Hardware managed Access Flag for Table Descriptor",
>>>> +		/*
>>>> +		 * Per Spec, software management of Access Flag for Table
>>>> +		 * descriptor is not supported, so make this feature system
>>>> +		 * wide.
>>>> +		 */
>>>
>>> I don't understand what you mean by this. Can you please clarify?
>>>
>>
>> Since this cannot be managed by the software, we should restrict all the CPUs
>> in the system to have and enable this feature which is indicated by
>> ARM64_CPUCAP_BOOT_CPU_FEATURE. It's not possible for part of the CPUs don't have
>> this feature and managed manually.
>>
>> I make this comment here since it's handled different from what ARM64_HW_DBM does (which
>> is ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE). Maybe it's redundant and can be dropped.
> 
> Ah, I see what you mean. I think this is still important to capture,
> but maybe in a clearer manner. Something like:
> 
> 	Contrary to the page/block access flag, the table access flag
> 	cannot be emulated in software (no access fault will occur).
> 	Therefore mandate that all CPUs have FEAT_HAFT.
> 

Will refine the comment here in v2. Thanks for the suggestion.

Thanks.
diff mbox series

Patch

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b3fc891f1544..f263ae4139a5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2127,6 +2127,26 @@  config ARM64_EPAN
 	  if the cpu does not implement the feature.
 endmenu # "ARMv8.7 architectural features"
 
+menu "ARMv8.9 architectural features"
+
+config ARM64_HAFT
+	bool "Support for Hardware managed Access Flag for Table Descriptor"
+	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 in TCR_EL1 (HAFT bit) on
+	  capable processors, 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 on supported CPUs. If unsure,
+	  say Y.
+
+endmenu # "ARMv8.9 architectural features"
+
 config ARM64_SVE
 	bool "ARM Scalable Vector Extension support"
 	default y
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 1f60aa1bc750..47bd29874e62 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -308,6 +308,11 @@ 
 #define TCR_TCMA1		(UL(1) << 58)
 #define TCR_DS			(UL(1) << 59)
 
+/*
+ * TCR2 Flags
+ */
+#define TCR2_HAFT		(UL(1) << 11)
+
 /*
  * TTBR.
  */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 646ecd3069fd..99402fd00f16 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2044,6 +2044,29 @@  static bool has_hw_dbm(const struct arm64_cpu_capabilities *cap,
 
 #endif
 
+#if CONFIG_ARM64_HAFT
+
+static void cpu_enable_haft(struct arm64_cpu_capabilities const *cap)
+{
+	u64 reg = read_sysreg_s(SYS_TCR2_EL1);
+
+	reg |= TCR2_HAFT;
+	write_sysreg_s(reg, SYS_TCR2_EL1);
+	isb();
+	local_flush_tlb_all();
+}
+
+static bool has_haft(const struct arm64_cpu_capabilities *cap, int scope)
+{
+	/* FEAT_HAFT relies on FEAT_TCR2 */
+	if (!this_cpu_has_cap(ARM64_HAS_TCR2))
+		return false;
+
+	return has_cpuid_feature(cap, scope);
+}
+
+#endif
+
 #ifdef CONFIG_ARM64_AMU_EXTN
 
 /*
@@ -2580,6 +2603,21 @@  static const struct arm64_cpu_capabilities arm64_features[] = {
 		.cpus = &dbm_cpus,
 		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, DBM)
 	},
+#endif
+#ifdef CONFIG_ARM64_HAFT
+	{
+		.desc = "Hardware managed Access Flag for Table Descriptor",
+		/*
+		 * Per Spec, software management of Access Flag for Table
+		 * descriptor is not supported, so make this feature system
+		 * wide.
+		 */
+		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
+		.capability = ARM64_HAFT,
+		.matches = has_haft,
+		.cpu_enable = cpu_enable_haft,
+		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, HAFT)
+	},
 #endif
 	{
 		.desc = "CRC32 instructions",
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index ac3429d892b9..0b7a3a237e5d 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -55,6 +55,7 @@  HAS_TLB_RANGE
 HAS_VA52
 HAS_VIRT_HOST_EXTN
 HAS_WFXT
+HAFT
 HW_DBM
 KVM_HVHE
 KVM_PROTECTED_MODE
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 7ceaa1e0b4bc..9b3d15ea8a63 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1688,6 +1688,7 @@  UnsignedEnum	3:0	HAFDBS
 	0b0000	NI
 	0b0001	AF
 	0b0010	DBM
+	0b0011	HAFT
 EndEnum
 EndSysreg