diff mbox series

[v4,2/4] arm64: cpufeatures: Add capability for LDAPR instruction

Message ID 20201103121721.5166-3-will@kernel.org (mailing list archive)
State New, archived
Headers show
Series None | expand

Commit Message

Will Deacon Nov. 3, 2020, 12:17 p.m. UTC
Armv8.3 introduced the LDAPR instruction, which provides weaker memory
ordering semantics than LDARi (RCpc vs RCsc). Generally, we provide an
RCsc implementation when implementing the Linux memory model, but LDAPR
can be used as a useful alternative to dependency ordering, particularly
when the compiler is capable of breaking the dependencies.

Since LDAPR is not available on all CPUs, add a cpufeature to detect it at
runtime and allow the instruction to be used with alternative code
patching.

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Will Deacon <will@kernel.org>
---
 arch/arm64/Kconfig               |  3 +++
 arch/arm64/include/asm/cpucaps.h |  3 ++-
 arch/arm64/kernel/cpufeature.c   | 10 ++++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

Comments

Mark Rutland Nov. 3, 2020, 12:44 p.m. UTC | #1
On Tue, Nov 03, 2020 at 12:17:19PM +0000, Will Deacon wrote:
> Armv8.3 introduced the LDAPR instruction, which provides weaker memory
> ordering semantics than LDARi (RCpc vs RCsc). Generally, we provide an
> RCsc implementation when implementing the Linux memory model, but LDAPR
> can be used as a useful alternative to dependency ordering, particularly
> when the compiler is capable of breaking the dependencies.
> 
> Since LDAPR is not available on all CPUs, add a cpufeature to detect it at
> runtime and allow the instruction to be used with alternative code
> patching.
> 
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Signed-off-by: Will Deacon <will@kernel.org>

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> ---
>  arch/arm64/Kconfig               |  3 +++
>  arch/arm64/include/asm/cpucaps.h |  3 ++-
>  arch/arm64/kernel/cpufeature.c   | 10 ++++++++++
>  3 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 1d466addb078..356c50b0447f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1388,6 +1388,9 @@ config ARM64_PAN
>  	 The feature is detected at runtime, and will remain as a 'nop'
>  	 instruction if the cpu does not implement the feature.
>  
> +config AS_HAS_LDAPR
> +	def_bool $(as-instr,.arch_extension rcpc)
> +
>  config ARM64_LSE_ATOMICS
>  	bool
>  	default ARM64_USE_LSE_ATOMICS
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> index e7d98997c09c..64ea0bb9f420 100644
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ b/arch/arm64/include/asm/cpucaps.h
> @@ -66,7 +66,8 @@
>  #define ARM64_HAS_TLB_RANGE			56
>  #define ARM64_MTE				57
>  #define ARM64_WORKAROUND_1508412		58
> +#define ARM64_HAS_LDAPR				59
>  
> -#define ARM64_NCAPS				59
> +#define ARM64_NCAPS				60
>  
>  #endif /* __ASM_CPUCAPS_H */
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index dcc165b3fc04..b7b6804cb931 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2136,6 +2136,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.cpu_enable = cpu_enable_mte,
>  	},
>  #endif /* CONFIG_ARM64_MTE */
> +	{
> +		.desc = "RCpc load-acquire (LDAPR)",
> +		.capability = ARM64_HAS_LDAPR,
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.sys_reg = SYS_ID_AA64ISAR1_EL1,
> +		.sign = FTR_UNSIGNED,
> +		.field_pos = ID_AA64ISAR1_LRCPC_SHIFT,
> +		.matches = has_cpuid_feature,
> +		.min_field_value = 1,
> +	},
>  	{},
>  };
>  
> -- 
> 2.29.1.341.ge80a0c044ae-goog
>
diff mbox series

Patch

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1d466addb078..356c50b0447f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1388,6 +1388,9 @@  config ARM64_PAN
 	 The feature is detected at runtime, and will remain as a 'nop'
 	 instruction if the cpu does not implement the feature.
 
+config AS_HAS_LDAPR
+	def_bool $(as-instr,.arch_extension rcpc)
+
 config ARM64_LSE_ATOMICS
 	bool
 	default ARM64_USE_LSE_ATOMICS
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index e7d98997c09c..64ea0bb9f420 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -66,7 +66,8 @@ 
 #define ARM64_HAS_TLB_RANGE			56
 #define ARM64_MTE				57
 #define ARM64_WORKAROUND_1508412		58
+#define ARM64_HAS_LDAPR				59
 
-#define ARM64_NCAPS				59
+#define ARM64_NCAPS				60
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index dcc165b3fc04..b7b6804cb931 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2136,6 +2136,16 @@  static const struct arm64_cpu_capabilities arm64_features[] = {
 		.cpu_enable = cpu_enable_mte,
 	},
 #endif /* CONFIG_ARM64_MTE */
+	{
+		.desc = "RCpc load-acquire (LDAPR)",
+		.capability = ARM64_HAS_LDAPR,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.sys_reg = SYS_ID_AA64ISAR1_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64ISAR1_LRCPC_SHIFT,
+		.matches = has_cpuid_feature,
+		.min_field_value = 1,
+	},
 	{},
 };