gcc7-aarch64-sls-miti-3.patch to backport aarch64 Straight Line Speculation mitigation [bsc#1172798, CVE-2020-13844] OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gcc7?expand=0&rev=199
607 lines
20 KiB
Diff
607 lines
20 KiB
Diff
Backport of below commit for bsc#1172798
|
|
Also adds the AARCH64_FL_SB support, not originally part of
|
|
this commit. And the added test sls-miti-retbr.c has -mbranch-protection
|
|
removed as that's not supported by our gcc7.
|
|
|
|
commit dc586a749228ecfb71f72ec2ca10e6f7b6874af3
|
|
Author: Matthew Malcomson <matthew.malcomson@arm.com>
|
|
Date: Thu Jul 9 09:11:59 2020 +0100
|
|
|
|
aarch64: Introduce SLS mitigation for RET and BR instructions
|
|
|
|
Instructions following RET or BR are not necessarily executed. In order
|
|
to avoid speculation past RET and BR we can simply append a speculation
|
|
barrier.
|
|
|
|
Since these speculation barriers will not be architecturally executed,
|
|
they are not expected to add a high performance penalty.
|
|
|
|
The speculation barrier is to be SB when targeting architectures which
|
|
have this enabled, and DSB SY + ISB otherwise.
|
|
|
|
We add tests for each of the cases where such an instruction was seen.
|
|
|
|
This is implemented by modifying each machine description pattern that
|
|
emits either a RET or a BR instruction. We choose not to use something
|
|
like `TARGET_ASM_FUNCTION_EPILOGUE` since it does not affect the
|
|
`indirect_jump`, `jump`, `sibcall_insn` and `sibcall_value_insn`
|
|
patterns and we find it preferable to implement the functionality in the
|
|
same way for every pattern.
|
|
|
|
There is one particular case which is slightly tricky. The
|
|
implementation of TARGET_ASM_TRAMPOLINE_TEMPLATE uses a BR which needs
|
|
to be mitigated against. The trampoline template is used *once* per
|
|
compilation unit, and the TRAMPOLINE_SIZE is exposed to the user via the
|
|
builtin macro __LIBGCC_TRAMPOLINE_SIZE__.
|
|
In the future we may implement function specific attributes to turn on
|
|
and off hardening on a per-function basis.
|
|
The fixed nature of the trampoline described above implies it will be
|
|
safer to ensure this speculation barrier is always used.
|
|
|
|
Testing:
|
|
Bootstrap and regtest done on aarch64-none-linux
|
|
Used a temporary hack(1) to use these options on every test in the
|
|
testsuite and a script to check that the output never emitted an
|
|
unmitigated RET or BR.
|
|
|
|
1) Temporary hack was a change to the testsuite to always use
|
|
`-save-temps` and run a script on the assembly output of those
|
|
compilations which produced one to ensure every RET or BR is immediately
|
|
followed by a speculation barrier.
|
|
|
|
(cherry picked from be178ecd5ac1fe1510d960ff95c66d0ff831afe1)
|
|
|
|
gcc/ChangeLog:
|
|
|
|
* config/aarch64/aarch64-protos.h (aarch64_sls_barrier): New.
|
|
* config/aarch64/aarch64.c (aarch64_output_casesi): Emit
|
|
speculation barrier after BR instruction if needs be.
|
|
(aarch64_trampoline_init): Handle ptr_mode value & adjust size
|
|
of code copied.
|
|
(aarch64_sls_barrier): New.
|
|
(aarch64_asm_trampoline_template): Add needed barriers.
|
|
* config/aarch64/aarch64.h (AARCH64_ISA_SB): New.
|
|
(TARGET_SB): New.
|
|
(TRAMPOLINE_SIZE): Account for barrier.
|
|
* config/aarch64/aarch64.md (indirect_jump, *casesi_dispatch,
|
|
simple_return, *do_return, *sibcall_insn, *sibcall_value_insn):
|
|
Emit barrier if needs be, also account for possible barrier using
|
|
"sls_length" attribute.
|
|
(sls_length): New attribute.
|
|
(length): Determine default using any non-default sls_length
|
|
value.
|
|
|
|
gcc/testsuite/ChangeLog:
|
|
|
|
* gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c: New test.
|
|
* gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c:
|
|
New test.
|
|
* gcc.target/aarch64/sls-mitigation/sls-mitigation.exp: New file.
|
|
* lib/target-supports.exp (check_effective_target_aarch64_asm_sb_ok):
|
|
New proc.
|
|
|
|
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64-protos.h
|
|
===================================================================
|
|
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64-protos.h
|
|
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64-protos.h
|
|
@@ -485,6 +485,7 @@ extern const atomic_ool_names aarch64_oo
|
|
extern const atomic_ool_names aarch64_ool_ldclr_names;
|
|
extern const atomic_ool_names aarch64_ool_ldeor_names;
|
|
|
|
+const char *aarch64_sls_barrier (int);
|
|
extern bool aarch64_harden_sls_retbr_p (void);
|
|
extern bool aarch64_harden_sls_blr_p (void);
|
|
|
|
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.c
|
|
===================================================================
|
|
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64.c
|
|
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.c
|
|
@@ -5736,15 +5736,28 @@ aarch64_asm_trampoline_template (FILE *f
|
|
{
|
|
if (TARGET_ILP32)
|
|
{
|
|
- asm_fprintf (f, "\tldr\tw%d, .+16\n", IP1_REGNUM - R0_REGNUM);
|
|
- asm_fprintf (f, "\tldr\tw%d, .+16\n", STATIC_CHAIN_REGNUM - R0_REGNUM);
|
|
+ asm_fprintf (f, "\tldr\tw%d, .+24\n", IP1_REGNUM - R0_REGNUM);
|
|
+ asm_fprintf (f, "\tldr\tw%d, .+24\n", STATIC_CHAIN_REGNUM - R0_REGNUM);
|
|
}
|
|
else
|
|
{
|
|
- asm_fprintf (f, "\tldr\t%s, .+16\n", reg_names [IP1_REGNUM]);
|
|
- asm_fprintf (f, "\tldr\t%s, .+20\n", reg_names [STATIC_CHAIN_REGNUM]);
|
|
+ asm_fprintf (f, "\tldr\t%s, .+24\n", reg_names [IP1_REGNUM]);
|
|
+ asm_fprintf (f, "\tldr\t%s, .+28\n", reg_names [STATIC_CHAIN_REGNUM]);
|
|
}
|
|
asm_fprintf (f, "\tbr\t%s\n", reg_names [IP1_REGNUM]);
|
|
+
|
|
+ /* We always emit a speculation barrier.
|
|
+ This is because the same trampoline template is used for every nested
|
|
+ function. Since nested functions are not particularly common or
|
|
+ performant we don't worry too much about the extra instructions to copy
|
|
+ around.
|
|
+ This is not yet a problem, since we have not yet implemented function
|
|
+ specific attributes to choose between hardening against straight line
|
|
+ speculation or not, but such function specific attributes are likely to
|
|
+ happen in the future. */
|
|
+ asm_fprintf (f, "\tdsb\tsy\n\tisb\n");
|
|
+
|
|
+ /* Padding for BTI at the beginning, which our gcc-7 backports don't do */
|
|
assemble_aligned_integer (4, const0_rtx);
|
|
assemble_aligned_integer (POINTER_BYTES, const0_rtx);
|
|
assemble_aligned_integer (POINTER_BYTES, const0_rtx);
|
|
@@ -5754,10 +5767,14 @@ static void
|
|
aarch64_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
|
|
{
|
|
rtx fnaddr, mem, a_tramp;
|
|
- const int tramp_code_sz = 16;
|
|
+ const int tramp_code_sz = 24;
|
|
|
|
/* Don't need to copy the trailing D-words, we fill those in below. */
|
|
- emit_block_move (m_tramp, assemble_trampoline_template (),
|
|
+ /* We create our own memory address in Pmode so that `emit_block_move` can
|
|
+ use parts of the backend which expect Pmode addresses. */
|
|
+ rtx temp = convert_memory_address (Pmode, XEXP (m_tramp, 0));
|
|
+ emit_block_move (gen_rtx_MEM (BLKmode, temp),
|
|
+ assemble_trampoline_template (),
|
|
GEN_INT (tramp_code_sz), BLOCK_OP_NORMAL);
|
|
mem = adjust_address (m_tramp, ptr_mode, tramp_code_sz);
|
|
fnaddr = XEXP (DECL_RTL (fndecl), 0);
|
|
@@ -5936,6 +5953,8 @@ aarch64_output_casesi (rtx *operands)
|
|
output_asm_insn (buf, operands);
|
|
output_asm_insn (patterns[index][1], operands);
|
|
output_asm_insn ("br\t%3", operands);
|
|
+ output_asm_insn (aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()),
|
|
+ operands);
|
|
assemble_label (asm_out_file, label);
|
|
return "";
|
|
}
|
|
@@ -14664,6 +14683,22 @@ aarch64_sched_can_speculate_insn (rtx_in
|
|
}
|
|
}
|
|
|
|
+/* Helper function for straight line speculation.
|
|
+ Return what barrier should be emitted for straight line speculation
|
|
+ mitigation.
|
|
+ When not mitigating against straight line speculation this function returns
|
|
+ an empty string.
|
|
+ When mitigating against straight line speculation, use:
|
|
+ * SB when the v8.5-A SB extension is enabled.
|
|
+ * DSB+ISB otherwise. */
|
|
+const char *
|
|
+aarch64_sls_barrier (int mitigation_required)
|
|
+{
|
|
+ return mitigation_required
|
|
+ ? (TARGET_SB ? "sb" : "dsb\tsy\n\tisb")
|
|
+ : "";
|
|
+}
|
|
+
|
|
/* Target-specific selftests. */
|
|
|
|
#if CHECKING_P
|
|
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.h
|
|
===================================================================
|
|
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64.h
|
|
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.h
|
|
@@ -141,6 +141,9 @@ extern unsigned aarch64_architecture_ver
|
|
/* ARMv8.3-A architecture extensions. */
|
|
#define AARCH64_FL_V8_3 (1 << 10) /* Has ARMv8.3-A features. */
|
|
|
|
+/* Speculation Barrier instruction supported. */
|
|
+#define AARCH64_FL_SB (1 << 25)
|
|
+
|
|
/* Has FP and SIMD. */
|
|
#define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD)
|
|
|
|
@@ -168,6 +171,8 @@ extern unsigned aarch64_architecture_ver
|
|
#define AARCH64_ISA_F16 (aarch64_isa_flags & AARCH64_FL_F16)
|
|
#define AARCH64_ISA_V8_3 (aarch64_isa_flags & AARCH64_FL_V8_3)
|
|
|
|
+#define AARCH64_ISA_SB (aarch64_isa_flags & AARCH64_FL_SB)
|
|
+
|
|
/* Crypto is an optional extension to AdvSIMD. */
|
|
#define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO)
|
|
|
|
@@ -193,6 +198,9 @@ extern unsigned aarch64_architecture_ver
|
|
#define TARGET_FIX_ERR_A53_835769_DEFAULT 1
|
|
#endif
|
|
|
|
+/* SB instruction is enabled through +sb. */
|
|
+#define TARGET_SB (AARCH64_ISA_SB)
|
|
+
|
|
/* Apply the workaround for Cortex-A53 erratum 835769. */
|
|
#define TARGET_FIX_ERR_A53_835769 \
|
|
((aarch64_fix_a53_err835769 == 2) \
|
|
@@ -805,8 +813,10 @@ typedef struct
|
|
|
|
#define RETURN_ADDR_RTX aarch64_return_addr
|
|
|
|
-/* 3 insns + padding + 2 pointer-sized entries. */
|
|
-#define TRAMPOLINE_SIZE (TARGET_ILP32 ? 24 : 32)
|
|
+/* BTI c + 3 insns
|
|
+ + sls barrier of DSB + ISB.
|
|
+ + 2 pointer-sized entries. */
|
|
+#define TRAMPOLINE_SIZE (24 + (TARGET_ILP32 ? 8 : 16))
|
|
|
|
/* Trampolines contain dwords, so must be dword aligned. */
|
|
#define TRAMPOLINE_ALIGNMENT 64
|
|
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.md
|
|
===================================================================
|
|
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64.md
|
|
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.md
|
|
@@ -187,8 +187,23 @@
|
|
;; will be disabled when !TARGET_SIMD.
|
|
(define_attr "simd" "no,yes" (const_string "no"))
|
|
|
|
+;; Attribute to specify that an alternative has the length of a single
|
|
+;; instruction plus a speculation barrier.
|
|
+(define_attr "sls_length" "none,retbr,casesi" (const_string "none"))
|
|
+
|
|
(define_attr "length" ""
|
|
- (const_int 4))
|
|
+ (cond [
|
|
+ (eq_attr "sls_length" "retbr")
|
|
+ (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 4)
|
|
+ (match_test "TARGET_SB") (const_int 8)]
|
|
+ (const_int 12))
|
|
+
|
|
+ (eq_attr "sls_length" "casesi")
|
|
+ (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 16)
|
|
+ (match_test "TARGET_SB") (const_int 20)]
|
|
+ (const_int 24))
|
|
+ ]
|
|
+ (const_int 4)))
|
|
|
|
;; Attribute that controls whether an alternative is enabled or not.
|
|
;; Currently it is only used to disable alternatives which touch fp or simd
|
|
@@ -235,8 +250,12 @@
|
|
(define_insn "indirect_jump"
|
|
[(set (pc) (match_operand:DI 0 "register_operand" "r"))]
|
|
""
|
|
- "br\\t%0"
|
|
- [(set_attr "type" "branch")]
|
|
+ {
|
|
+ output_asm_insn ("br\\t%0", operands);
|
|
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
|
+ }
|
|
+ [(set_attr "type" "branch")
|
|
+ (set_attr "sls_length" "retbr")]
|
|
)
|
|
|
|
(define_insn "jump"
|
|
@@ -508,7 +527,7 @@
|
|
"*
|
|
return aarch64_output_casesi (operands);
|
|
"
|
|
- [(set_attr "length" "16")
|
|
+ [(set_attr "sls_length" "casesi")
|
|
(set_attr "type" "branch")]
|
|
)
|
|
|
|
@@ -583,14 +602,18 @@
|
|
[(return)]
|
|
""
|
|
{
|
|
+ const char *ret = NULL;
|
|
if (aarch64_return_address_signing_enabled ()
|
|
&& TARGET_ARMV8_3
|
|
&& !crtl->calls_eh_return)
|
|
- return "retaa";
|
|
-
|
|
- return "ret";
|
|
+ ret = "retaa";
|
|
+ else
|
|
+ ret = "ret";
|
|
+ output_asm_insn (ret, operands);
|
|
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
|
}
|
|
- [(set_attr "type" "branch")]
|
|
+ [(set_attr "type" "branch")
|
|
+ (set_attr "sls_length" "retbr")]
|
|
)
|
|
|
|
(define_expand "return"
|
|
@@ -602,8 +625,12 @@
|
|
(define_insn "simple_return"
|
|
[(simple_return)]
|
|
""
|
|
- "ret"
|
|
- [(set_attr "type" "branch")]
|
|
+ {
|
|
+ output_asm_insn ("ret", operands);
|
|
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
|
+ }
|
|
+ [(set_attr "type" "branch")
|
|
+ (set_attr "sls_length" "retbr")]
|
|
)
|
|
|
|
(define_insn "*cb<optab><mode>1"
|
|
@@ -903,10 +930,16 @@
|
|
(return)
|
|
(use (match_operand 2 "" ""))]
|
|
"SIBLING_CALL_P (insn)"
|
|
- "@
|
|
- br\\t%0
|
|
- b\\t%a0"
|
|
- [(set_attr "type" "branch, branch")]
|
|
+ {
|
|
+ if (which_alternative == 0)
|
|
+ {
|
|
+ output_asm_insn ("br\\t%0", operands);
|
|
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
|
+ }
|
|
+ return "b\\t%c0";
|
|
+ }
|
|
+ [(set_attr "type" "branch, branch")
|
|
+ (set_attr "sls_length" "retbr,none")]
|
|
)
|
|
|
|
(define_insn "*sibcall_value_insn"
|
|
@@ -917,10 +950,16 @@
|
|
(return)
|
|
(use (match_operand 3 "" ""))]
|
|
"SIBLING_CALL_P (insn)"
|
|
- "@
|
|
- br\\t%1
|
|
- b\\t%a1"
|
|
- [(set_attr "type" "branch, branch")]
|
|
+ {
|
|
+ if (which_alternative == 0)
|
|
+ {
|
|
+ output_asm_insn ("br\\t%1", operands);
|
|
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
|
+ }
|
|
+ return "b\\t%c1";
|
|
+ }
|
|
+ [(set_attr "type" "branch, branch")
|
|
+ (set_attr "sls_length" "retbr,none")]
|
|
)
|
|
|
|
;; Call subroutine returning any type.
|
|
Index: gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c
|
|
@@ -0,0 +1,15 @@
|
|
+/* Avoid ILP32 since pacret is only available for LP64 */
|
|
+/* { dg-do compile { target { ! ilp32 } } } */
|
|
+/* { dg-additional-options "-mharden-sls=retbr -march=armv8.3-a" } */
|
|
+
|
|
+/* Testing the do_return pattern for retaa. */
|
|
+long retbr_subcall(void);
|
|
+long retbr_do_return_retaa(void)
|
|
+{
|
|
+ return retbr_subcall()+1;
|
|
+}
|
|
+
|
|
+/* Ensure there are no BR or RET instructions which are not directly followed
|
|
+ by a speculation barrier. */
|
|
+/* { dg-final { scan-assembler-not {\t(br|ret|retaa)\tx[0-9][0-9]?\n\t(?!dsb\tsy\n\tisb)} } } */
|
|
+/* { dg-final { scan-assembler-not {ret\t} } } */
|
|
Index: gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c
|
|
@@ -0,0 +1,119 @@
|
|
+/* We ensure that -Wpedantic is off since it complains about the trampolines
|
|
+ we explicitly want to test. */
|
|
+/* { dg-additional-options "-mharden-sls=retbr -Wno-pedantic " } */
|
|
+/*
|
|
+ Ensure that the SLS hardening of RET and BR leaves no unprotected RET/BR
|
|
+ instructions.
|
|
+ */
|
|
+typedef int (foo) (int, int);
|
|
+typedef void (bar) (int, int);
|
|
+struct sls_testclass {
|
|
+ foo *x;
|
|
+ bar *y;
|
|
+ int left;
|
|
+ int right;
|
|
+};
|
|
+
|
|
+int
|
|
+retbr_sibcall_value_insn (struct sls_testclass x)
|
|
+{
|
|
+ return x.x(x.left, x.right);
|
|
+}
|
|
+
|
|
+void
|
|
+retbr_sibcall_insn (struct sls_testclass x)
|
|
+{
|
|
+ x.y(x.left, x.right);
|
|
+}
|
|
+
|
|
+/* Aim to test two different returns.
|
|
+ One that introduces a tail call in the middle of the function, and one that
|
|
+ has a normal return. */
|
|
+int
|
|
+retbr_multiple_returns (struct sls_testclass x)
|
|
+{
|
|
+ int temp;
|
|
+ if (x.left % 10)
|
|
+ return x.x(x.left, 100);
|
|
+ else if (x.right % 20)
|
|
+ {
|
|
+ return x.x(x.left * x.right, 100);
|
|
+ }
|
|
+ temp = x.left % x.right;
|
|
+ temp *= 100;
|
|
+ temp /= 2;
|
|
+ return temp % 3;
|
|
+}
|
|
+
|
|
+void
|
|
+retbr_multiple_returns_void (struct sls_testclass x)
|
|
+{
|
|
+ if (x.left % 10)
|
|
+ {
|
|
+ x.y(x.left, 100);
|
|
+ }
|
|
+ else if (x.right % 20)
|
|
+ {
|
|
+ x.y(x.left * x.right, 100);
|
|
+ }
|
|
+ return;
|
|
+}
|
|
+
|
|
+/* Testing the casesi jump via register. */
|
|
+__attribute__ ((optimize ("Os")))
|
|
+int
|
|
+retbr_casesi_dispatch (struct sls_testclass x)
|
|
+{
|
|
+ switch (x.left)
|
|
+ {
|
|
+ case -5:
|
|
+ return -2;
|
|
+ case -3:
|
|
+ return -1;
|
|
+ case 0:
|
|
+ return 0;
|
|
+ case 3:
|
|
+ return 1;
|
|
+ case 5:
|
|
+ break;
|
|
+ default:
|
|
+ __builtin_unreachable ();
|
|
+ }
|
|
+ return x.right;
|
|
+}
|
|
+
|
|
+/* Testing the BR in trampolines is mitigated against. */
|
|
+void f1 (void *);
|
|
+void f3 (void *, void (*)(void *));
|
|
+void f2 (void *);
|
|
+
|
|
+int
|
|
+retbr_trampolines (void *a, int b)
|
|
+{
|
|
+ if (!b)
|
|
+ {
|
|
+ f1 (a);
|
|
+ return 1;
|
|
+ }
|
|
+ if (b)
|
|
+ {
|
|
+ void retbr_tramp_internal (void *c)
|
|
+ {
|
|
+ if (c == a)
|
|
+ f2 (c);
|
|
+ }
|
|
+ f3 (a, retbr_tramp_internal);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* Testing the indirect_jump pattern. */
|
|
+void
|
|
+retbr_indirect_jump (int *buf)
|
|
+{
|
|
+ __builtin_longjmp(buf, 1);
|
|
+}
|
|
+
|
|
+/* Ensure there are no BR or RET instructions which are not directly followed
|
|
+ by a speculation barrier. */
|
|
+/* { dg-final { scan-assembler-not {\t(br|ret|retaa)\tx[0-9][0-9]?\n\t(?!dsb\tsy\n\tisb|sb)} } } */
|
|
Index: gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp
|
|
@@ -0,0 +1,73 @@
|
|
+# Regression driver for SLS mitigation on AArch64.
|
|
+# Copyright (C) 2020 Free Software Foundation, Inc.
|
|
+# Contributed by ARM Ltd.
|
|
+#
|
|
+# This file is part of GCC.
|
|
+#
|
|
+# GCC is free software; you can redistribute it and/or modify it
|
|
+# under the terms of the GNU General Public License as published by
|
|
+# the Free Software Foundation; either version 3, or (at your option)
|
|
+# any later version.
|
|
+#
|
|
+# GCC is distributed in the hope that it will be useful, but
|
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+# General Public License for more details.
|
|
+#
|
|
+# You should have received a copy of the GNU General Public License
|
|
+# along with GCC; see the file COPYING3. If not see
|
|
+# <http://www.gnu.org/licenses/>. */
|
|
+
|
|
+# Exit immediately if this isn't an AArch64 target.
|
|
+if {![istarget aarch64*-*-*] } then {
|
|
+ return
|
|
+}
|
|
+
|
|
+# Load support procs.
|
|
+load_lib gcc-dg.exp
|
|
+load_lib torture-options.exp
|
|
+
|
|
+# If a testcase doesn't have special options, use these.
|
|
+global DEFAULT_CFLAGS
|
|
+if ![info exists DEFAULT_CFLAGS] then {
|
|
+ set DEFAULT_CFLAGS " "
|
|
+}
|
|
+
|
|
+# Initialize `dg'.
|
|
+dg-init
|
|
+torture-init
|
|
+
|
|
+# Use different architectures as well as the normal optimisation options.
|
|
+# (i.e. use both SB and DSB+ISB barriers).
|
|
+
|
|
+set save-dg-do-what-default ${dg-do-what-default}
|
|
+# Main loop.
|
|
+# Run with torture tests (i.e. a bunch of different optimisation levels) just
|
|
+# to increase test coverage.
|
|
+set dg-do-what-default assemble
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
|
|
+ "-save-temps" $DEFAULT_CFLAGS
|
|
+
|
|
+# Run the same tests but this time with SB extension.
|
|
+# Since not all supported assemblers will support that extension we decide
|
|
+# whether to assemble or just compile based on whether the extension is
|
|
+# supported for the available assembler.
|
|
+
|
|
+set templist {}
|
|
+foreach x $DG_TORTURE_OPTIONS {
|
|
+ lappend templist "$x -march=armv8.3-a+sb "
|
|
+ lappend templist "$x -march=armv8-a+sb "
|
|
+}
|
|
+set-torture-options $templist
|
|
+if { [check_effective_target_aarch64_asm_sb_ok] } {
|
|
+ set dg-do-what-default assemble
|
|
+} else {
|
|
+ set dg-do-what-default compile
|
|
+}
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
|
|
+ "-save-temps" $DEFAULT_CFLAGS
|
|
+set dg-do-what-default ${save-dg-do-what-default}
|
|
+
|
|
+# All done.
|
|
+torture-finish
|
|
+dg-finish
|
|
Index: gcc-7.5.0+r278197/gcc/testsuite/lib/target-supports.exp
|
|
===================================================================
|
|
--- gcc-7.5.0+r278197.orig/gcc/testsuite/lib/target-supports.exp
|
|
+++ gcc-7.5.0+r278197/gcc/testsuite/lib/target-supports.exp
|
|
@@ -7929,7 +7929,7 @@ proc check_effective_target_aarch64_tiny
|
|
# Create functions to check that the AArch64 assembler supports the
|
|
# various architecture extensions via the .arch_extension pseudo-op.
|
|
|
|
-foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse"} {
|
|
+foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "sb"} {
|
|
eval [string map [list FUNC $aarch64_ext] {
|
|
proc check_effective_target_aarch64_asm_FUNC_ok { } {
|
|
if { [istarget aarch64*-*-*] } {
|
|
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64-option-extensions.def
|
|
===================================================================
|
|
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64-option-extensions.def
|
|
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64-option-extensions.def
|
|
@@ -60,4 +60,7 @@ AARCH64_OPT_EXTENSION("lse", AARCH64_FL_
|
|
Disabling "fp16" just disables "fp16". */
|
|
AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, 0, "fphp asimdhp")
|
|
|
|
+/* Enabling/Disabling "sb" only changes "sb". */
|
|
+AARCH64_OPT_EXTENSION("sb", AARCH64_FL_SB, 0, 0, "sb")
|
|
+
|
|
#undef AARCH64_OPT_EXTENSION
|