Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1397188 > unrolled thread

[PATCH 0/6] arm64: Extend Cortex-A53 errata workaround

Started byAndre Przywara <andre.przywara@arm.com>
First post2016-05-09 18:50 +0200
Last post2016-05-09 19:00 +0200
Articles 4 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/6] arm64: Extend Cortex-A53 errata workaround Andre Przywara <andre.przywara@arm.com> - 2016-05-09 18:50 +0200
    [PATCH 1/6] arm64: alternatives: drop enable parameter from _else and _endif macro Andre Przywara <andre.przywara@arm.com> - 2016-05-09 19:00 +0200
    [PATCH 3/6] arm64: include alternative handling in dcache_by_line_op Andre Przywara <andre.przywara@arm.com> - 2016-05-09 19:00 +0200
    [PATCH 4/6] arm64: errata: Calling enable functions for CPU errata too Andre Przywara <andre.przywara@arm.com> - 2016-05-09 19:00 +0200

#1397188 — [PATCH 0/6] arm64: Extend Cortex-A53 errata workaround

FromAndre Przywara <andre.przywara@arm.com>
Date2016-05-09 18:50 +0200
Subject[PATCH 0/6] arm64: Extend Cortex-A53 errata workaround
Message-ID<rwWxA-11Z-19@gated-at.bofh.it>
According to the errata documentation for the ARM errata 819472, 826319,
827319 and 824069, in addition to the already covered promotion of
"dc cvac" cache maintenance instructions to "dc civac"[1], we also need
to promote "dc cvau" operations.
Also as cache maintenance instructions on ARMv8 can be issued by EL0 as
well, we unfortunately have to promote them too, which is only possible
by means of trap-and-emulate.

These patches cover all in-kernel users of "dc cvau" and make sure
they are using "dc civac" if run on an affected core.
In addition if at least one core in the system has one of the above
mentioned erratas, we set the respective bit in SCTLR to trap cache
maintenance instructions from EL0 to EL1 on all CPUs, where we "emulate"
them by executing the potentially fixed instruction on behalf of userspace.

Apart from the actual patches 2/6 and 6/6, which do the main work, the
other patches are cleanups and do refactoring to make the promotion and
trapping of EL0 cache maintenance easier.

Tested on a Juno R0 with an userspace tool to issue various cache
maintenance instructions (including one with triggers a SIGSEGV) and
verified with some debugfs entries.
At least one LTP test also issues around 100 cache maintenance
instructions, which this code survived happily.

Cheers,
Andre.

[1] commit 301bcfac4289 ("arm64: add Cortex-A53 cache errata workaround")

Andre Przywara (6):
  arm64: alternatives: drop enable parameter from _else and _endif macro
  arm64: fix "dc cvau" cache operation on errata-affected core
  arm64: include alternative handling in dcache_by_line_op
  arm64: errata: Calling enable functions for CPU errata too
  arm64: consolidate signal injection on emulation errors
  arm64: trap userspace "dc cvau" cache operation on errata-affected
    core

 arch/arm64/include/asm/alternative.h |  28 +++++++--
 arch/arm64/include/asm/cpufeature.h  |   2 +
 arch/arm64/include/asm/processor.h   |   1 +
 arch/arm64/include/asm/sysreg.h      |   2 +-
 arch/arm64/include/asm/traps.h       |   3 +
 arch/arm64/kernel/armv8_deprecated.c |  13 ++--
 arch/arm64/kernel/cpu_errata.c       |   7 +++
 arch/arm64/kernel/cpufeature.c       |   4 +-
 arch/arm64/kernel/entry.S            |  12 +++-
 arch/arm64/kernel/traps.c            | 111 +++++++++++++++++++++++++++++++----
 arch/arm64/mm/cache.S                |   2 +-
 arch/arm64/mm/proc-macros.S          |   9 ++-
 12 files changed, 164 insertions(+), 30 deletions(-)

-- 
2.7.3

[toc] | [next] | [standalone]


#1397189 — [PATCH 1/6] arm64: alternatives: drop enable parameter from _else and _endif macro

FromAndre Przywara <andre.przywara@arm.com>
Date2016-05-09 19:00 +0200
Subject[PATCH 1/6] arm64: alternatives: drop enable parameter from _else and _endif macro
Message-ID<rwWHf-16Q-3@gated-at.bofh.it>
In reply to#1397188
Commit 77ee306c0aea9 ("arm64: alternatives: add enable parameter to
conditional asm macros") extended the alternative assembly macros.
Unfortunately this does not really work as one would expect, as the
enable parameter in fact correctly protects the alternative section
magic, but not the actual code sequences.
So if enable is false, we will have the original instruction(s) _and_
the alternative ones in the file, which is just wrong.
To make this work one would need to additionally protect the
alternative sequence with extra .if directives, which makes
the intention of the enable parameter rather pointless.
Instead users should directly guard the whole "_else; insn; _endif"
sequence with .if directives.
Add a comment describing this usage and drop the enable parameter from
the alternative_else and alternative_endif macros.

This reverts parts of commit 77ee306c0aea ("arm64: alternatives: add
enable parameter to conditional asm macros").

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm64/include/asm/alternative.h | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
index beccbde..502c9ef 100644
--- a/arch/arm64/include/asm/alternative.h
+++ b/arch/arm64/include/asm/alternative.h
@@ -94,6 +94,8 @@ void apply_alternatives(void *start, size_t length);
  *
  * The code that follows this macro will be assembled and linked as
  * normal. There are no restrictions on this code.
+ * If you use the enable parameter, see the comments below for _else
+ * and _endif.
  */
 .macro alternative_if_not cap, enable = 1
 	.if \enable
@@ -117,23 +119,33 @@ void apply_alternatives(void *start, size_t length);
  * 2. Not contain a branch target that is used outside of the
  *    alternative sequence it is defined in (branches into an
  *    alternative sequence are not fixed up).
+ *
+ * If you used the optional enable parameter in the opening
+ * alternative_if_not macro above, please protect the whole _else
+ * branch with an .if directive:
+ *	alternative_if_not CAP_SOMETHING, condition
+ *		orig_insn
+ *	.if condition
+ *	alternative_else
+ *		repl_insn
+ *	alternative_endif
+ *	.endif
  */
-.macro alternative_else, enable = 1
-	.if \enable
+.macro alternative_else
 662:	.pushsection .altinstr_replacement, "ax"
 663:
-	.endif
 .endm
 
 /*
  * Complete an alternative code sequence.
+ *
+ * Please mind the comment at alternative_else above if you used the
+ * optional enable parameter with the opening alternative_if_not macro.
  */
-.macro alternative_endif, enable = 1
-	.if \enable
+.macro alternative_endif
 664:	.popsection
 	.org	. - (664b-663b) + (662b-661b)
 	.org	. - (662b-661b) + (664b-663b)
-	.endif
 .endm
 
 #define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...)	\
-- 
2.7.3

[toc] | [prev] | [next] | [standalone]


#1397190 — [PATCH 3/6] arm64: include alternative handling in dcache_by_line_op

FromAndre Przywara <andre.przywara@arm.com>
Date2016-05-09 19:00 +0200
Subject[PATCH 3/6] arm64: include alternative handling in dcache_by_line_op
Message-ID<rwWHg-16Q-21@gated-at.bofh.it>
In reply to#1397188
The newly introduced dcache_by_line_op macro is used at least in
one occassion at the moment to issue a "dc cvau" instruction,
which is affected by ARM errata 819472, 826319, 827319 and 824069.
Change the macro to allow for alternative patching in there to
protect affected Cortex-A53 cores.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm64/mm/proc-macros.S | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/proc-macros.S b/arch/arm64/mm/proc-macros.S
index e6a30e1..5786017 100644
--- a/arch/arm64/mm/proc-macros.S
+++ b/arch/arm64/mm/proc-macros.S
@@ -78,7 +78,14 @@
 	add	\size, \kaddr, \size
 	sub	\tmp2, \tmp1, #1
 	bic	\kaddr, \kaddr, \tmp2
-9998:	dc	\op, \kaddr
+9998:
+	alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE, (\op == cvau || \op == cvac)
+	dc	\op, \kaddr
+	.if	(\op == cvau || \op == cvac)
+	alternative_else
+	dc	civac, \kaddr
+	alternative_endif
+	.endif
 	add	\kaddr, \kaddr, \tmp1
 	cmp	\kaddr, \size
 	b.lo	9998b
-- 
2.7.3

[toc] | [prev] | [next] | [standalone]


#1397191 — [PATCH 4/6] arm64: errata: Calling enable functions for CPU errata too

FromAndre Przywara <andre.przywara@arm.com>
Date2016-05-09 19:00 +0200
Subject[PATCH 4/6] arm64: errata: Calling enable functions for CPU errata too
Message-ID<rwWHg-16Q-25@gated-at.bofh.it>
In reply to#1397188
Currently we call the (optional) enable function for CPU _features_
only. As CPU _errata_ descriptions share the same data structure and
having an enable function is useful for errata as well (for instance
to set bits in SCTLR), lets call it when enumerating erratas too.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm64/include/asm/cpufeature.h | 2 ++
 arch/arm64/kernel/cpu_errata.c      | 5 +++++
 arch/arm64/kernel/cpufeature.c      | 4 ++--
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b9b6494..cb8fb2c 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -174,7 +174,9 @@ void __init setup_cpu_features(void);
 
 void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
 			    const char *info);
+void enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps);
 void check_local_cpu_errata(void);
+void __init enable_cpu_errata(void);
 
 void verify_local_cpu_capabilities(void);
 
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 06afd04..64cb71d 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -105,3 +105,8 @@ void check_local_cpu_errata(void)
 {
 	update_cpu_capabilities(arm64_errata, "enabling workaround for");
 }
+
+void __init enable_cpu_errata(void)
+{
+	enable_cpu_capabilities(arm64_errata);
+}
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 943f514..04a324f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -835,8 +835,7 @@ void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
  * Run through the enabled capabilities and enable() it on all active
  * CPUs
  */
-static void __init
-enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
+void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
 {
 	int i;
 
@@ -974,6 +973,7 @@ void __init setup_cpu_features(void)
 
 	/* Set the CPU feature capabilies */
 	setup_feature_capabilities();
+	enable_cpu_errata();
 	setup_cpu_hwcaps();
 
 	/* Advertise that we have computed the system capabilities */
-- 
2.7.3

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web