aarch64: (GCC-9 Backport) New Straight Line Speculation (SLS) mitigation flags

2020-07-21 Thread Matthew Malcomson
Here we introduce the flags that will be used for straight line speculation.

The new flag introduced is `-mharden-sls=`.
This flag can take arguments of `none`, `all`, or a comma seperated list
of one or more of `retbr` or `blr`.
`none` indicates no special mitigation of the straight line speculation
vulnerability.
`all` requests all mitigations currently implemented.
`retbr` requests that the RET and BR instructions have a speculation
barrier inserted after them.
`blr` requests that BLR instructions are replaced by a BL to a function
stub using a BR with a speculation barrier after it.

Setting this on a per-function basis using attributes or the like is not
enabled, but may be in the future.

gcc/ChangeLog:

* config/aarch64/aarch64-protos.h (aarch64_harden_sls_retbr_p):
New.
(aarch64_harden_sls_blr_p): New.
* config/aarch64/aarch64.c (enum aarch64_sls_hardening_type):
New.
(aarch64_harden_sls_retbr_p): New.
(aarch64_harden_sls_blr_p): New.
(aarch64_validate_sls_mitigation): New.
(aarch64_override_options): Parse options for SLS mitigation.
* config/aarch64/aarch64.opt (-mharden-sls): New option.
* doc/invoke.texi: Document new option.

(cherry picked from commit a9ba2a9b77bec7eacaf066801f22d1c366a2bc86)


### Attachment also inlined for ease of reply###


diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 
af2a17f0bf3b50a306b14d8c0aa431269f54ef2e..db5a6a3a1813abbbeeaaa7009466ac58595e12bc
 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -658,4 +658,7 @@ extern const atomic_ool_names aarch64_ool_ldset_names;
 extern const atomic_ool_names aarch64_ool_ldclr_names;
 extern const atomic_ool_names aarch64_ool_ldeor_names;
 
+extern bool aarch64_harden_sls_retbr_p (void);
+extern bool aarch64_harden_sls_blr_p (void);
+
 #endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 
1b6e67ccd53da05c88b13cac8b524ba2b8cfe43f..0903370b6128e19016f97cb6b0fd44e6b51e569e
 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -11791,6 +11791,79 @@ aarch64_validate_mcpu (const char *str, const struct 
processor **res,
   return false;
 }
 
+/* Straight line speculation indicators.  */
+enum aarch64_sls_hardening_type
+{
+  SLS_NONE = 0,
+  SLS_RETBR = 1,
+  SLS_BLR = 2,
+  SLS_ALL = 3,
+};
+static enum aarch64_sls_hardening_type aarch64_sls_hardening;
+
+/* Return whether we should mitigatate Straight Line Speculation for the RET
+   and BR instructions.  */
+bool
+aarch64_harden_sls_retbr_p (void)
+{
+  return aarch64_sls_hardening & SLS_RETBR;
+}
+
+/* Return whether we should mitigatate Straight Line Speculation for the BLR
+   instruction.  */
+bool
+aarch64_harden_sls_blr_p (void)
+{
+  return aarch64_sls_hardening & SLS_BLR;
+}
+
+/* As of yet we only allow setting these options globally, in the future we may
+   allow setting them per function.  */
+static void
+aarch64_validate_sls_mitigation (const char *const_str)
+{
+  char *token_save = NULL;
+  char *str = NULL;
+
+  if (strcmp (const_str, "none") == 0)
+{
+  aarch64_sls_hardening = SLS_NONE;
+  return;
+}
+  if (strcmp (const_str, "all") == 0)
+{
+  aarch64_sls_hardening = SLS_ALL;
+  return;
+}
+
+  char *str_root = xstrdup (const_str);
+  str = strtok_r (str_root, ",", &token_save);
+  if (!str)
+error ("invalid argument given to %<-mharden-sls=%>");
+
+  int temp = SLS_NONE;
+  while (str)
+{
+  if (strcmp (str, "blr") == 0)
+   temp |= SLS_BLR;
+  else if (strcmp (str, "retbr") == 0)
+   temp |= SLS_RETBR;
+  else if (strcmp (str, "none") == 0 || strcmp (str, "all") == 0)
+   {
+ error ("%<%s%> must be by itself for %<-mharden-sls=%>", str);
+ break;
+   }
+  else
+   {
+ error ("invalid argument %<%s%> for %<-mharden-sls=%>", str);
+ break;
+   }
+  str = strtok_r (NULL, ",", &token_save);
+}
+  aarch64_sls_hardening = (aarch64_sls_hardening_type) temp;
+  free (str_root);
+}
+
 /* Parses CONST_STR for branch protection features specified in
aarch64_branch_protect_types, and set any global variables required.  
Returns
the parsing result and assigns LAST_STR to the last processed token from
@@ -12029,6 +12102,9 @@ aarch64_override_options (void)
   selected_arch = NULL;
   selected_tune = NULL;
 
+  if (aarch64_harden_sls_string)
+aarch64_validate_sls_mitigation (aarch64_harden_sls_string);
+
   if (aarch64_branch_protection_string)
 aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
 
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 
f474a28eb9234cf87b22492c4396d5a31857cd39..4beb2d3d243c4ca36e7604c02ab5d9e80955f55a
 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch

Re: [Patch 1/3] aarch64: New Straight Line Speculation (SLS) mitigation flags

2020-07-06 Thread Richard Sandiford
Matthew Malcomson  writes:
> +  aarch64_sls_hardening = SLS_NONE;
> +  if (strcmp (const_str, "none") == 0)
> +{
> +  aarch64_sls_hardening = SLS_NONE;
> +  return;

Gah, I totally misread the previous patch and didn't see that
you were already setting aarch64_sls_hardening to SLS_NONE above.
So this line is obviously redundant after all, sorry for the noise.

OK with the line above removed, thanks.

Richard


Re: [Patch 1/3] aarch64: New Straight Line Speculation (SLS) mitigation flags

2020-07-03 Thread Matthew Malcomson
With suggestions applied.


Here we introduce the flags that will be used for straight line speculation.

The new flag introduced is `-mharden-sls=`.
This flag can take arguments of `none`, `all`, or a comma seperated list of one
or more of `retbr` or `blr`.
`none` indicates no special mitigation of the straight line speculation
vulnerability.
`all` requests all mitigations currently implemented.
`retbr` requests that the RET and BR instructions have a speculation barrier
inserted after them.
`blr` requests that BLR instructions are replaced by a BL to a function stub
using a BR with a speculation barrier after it.

Setting this on a per-function basis using attributes or the like is not
enabled, but may be in the future.

gcc/ChangeLog:

2020-07-03  Matthew Malcomson  

* config/aarch64/aarch64-protos.h (aarch64_harden_sls_retbr_p):
New.
(aarch64_harden_sls_blr_p): New.
* config/aarch64/aarch64.c (enum aarch64_sls_hardening_type):
New.
(aarch64_harden_sls_retbr_p): New.
(aarch64_harden_sls_blr_p): New.
(aarch64_validate_sls_mitigation): New.
(aarch64_override_options): Parse options for SLS mitigation.
* config/aarch64/aarch64.opt (-mharden-sls): New option.
* doc/invoke.texi: Document new option.



### Attachment also inlined for ease of reply###


diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 
9e43adb7db0373df6cc5ef1d2b22f217aca2aad2..8ca67d7e69edaf73c84f079e7e1c483009ad10c0
 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -780,4 +780,7 @@ extern const atomic_ool_names aarch64_ool_ldeor_names;
 
 tree aarch64_resolve_overloaded_builtin_general (location_t, tree, void *);
 
+extern bool aarch64_harden_sls_retbr_p (void);
+extern bool aarch64_harden_sls_blr_p (void);
+
 #endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 
f3551a73d87c4e686540f39224985592c3c66fd1..b1a7c10c4eaadd78eb45926c23efc51a8272b5fd
 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -14502,6 +14502,80 @@ aarch64_validate_mcpu (const char *str, const struct 
processor **res,
   return false;
 }
 
+/* Straight line speculation indicators.  */
+enum aarch64_sls_hardening_type
+{
+  SLS_NONE = 0,
+  SLS_RETBR = 1,
+  SLS_BLR = 2,
+  SLS_ALL = 3,
+};
+static enum aarch64_sls_hardening_type aarch64_sls_hardening;
+
+/* Return whether we should mitigatate Straight Line Speculation for the RET
+   and BR instructions.  */
+bool
+aarch64_harden_sls_retbr_p (void)
+{
+  return aarch64_sls_hardening & SLS_RETBR;
+}
+
+/* Return whether we should mitigatate Straight Line Speculation for the BLR
+   instruction.  */
+bool
+aarch64_harden_sls_blr_p (void)
+{
+  return aarch64_sls_hardening & SLS_BLR;
+}
+
+/* As of yet we only allow setting these options globally, in the future we may
+   allow setting them per function.  */
+static void
+aarch64_validate_sls_mitigation (const char *const_str)
+{
+  char *token_save = NULL;
+  char *str = NULL;
+
+  aarch64_sls_hardening = SLS_NONE;
+  if (strcmp (const_str, "none") == 0)
+{
+  aarch64_sls_hardening = SLS_NONE;
+  return;
+}
+  if (strcmp (const_str, "all") == 0)
+{
+  aarch64_sls_hardening = SLS_ALL;
+  return;
+}
+
+  char *str_root = xstrdup (const_str);
+  str = strtok_r (str_root, ",", &token_save);
+  if (!str)
+error ("invalid argument given to %<-mharden-sls=%>");
+
+  int temp = SLS_NONE;
+  while (str)
+{
+  if (strcmp (str, "blr") == 0)
+   temp |= SLS_BLR;
+  else if (strcmp (str, "retbr") == 0)
+   temp |= SLS_RETBR;
+  else if (strcmp (str, "none") == 0 || strcmp (str, "all") == 0)
+   {
+ error ("%<%s%> must be by itself for %<-mharden-sls=%>", str);
+ break;
+   }
+  else
+   {
+ error ("invalid argument %<%s%> for %<-mharden-sls=%>", str);
+ break;
+   }
+  str = strtok_r (NULL, ",", &token_save);
+}
+  aarch64_sls_hardening = (aarch64_sls_hardening_type) temp;
+  free (str_root);
+}
+
 /* Parses CONST_STR for branch protection features specified in
aarch64_branch_protect_types, and set any global variables required.  
Returns
the parsing result and assigns LAST_STR to the last processed token from
@@ -14746,6 +14820,9 @@ aarch64_override_options (void)
   selected_arch = NULL;
   selected_tune = NULL;
 
+  if (aarch64_harden_sls_string)
+aarch64_validate_sls_mitigation (aarch64_harden_sls_string);
+
   if (aarch64_branch_protection_string)
 aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
 
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 
d99d14c137d8774d3c8dab860d475f68c01a2817..5170361fd5e5721e044d1664e522b2718f654b8e
 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/a

Re: [Patch 1/3] aarch64: New Straight Line Speculation (SLS) mitigation flags

2020-06-23 Thread Richard Sandiford
Matthew Malcomson  writes:
> On 23/06/2020 16:48, Richard Sandiford wrote:
>> Matthew Malcomson  writes:
>>> @@ -14466,6 +14466,81 @@ aarch64_validate_mcpu (const char *str, const 
>>> struct processor **res,
>>> return false;
>>>   mfix-cortex-a53-835769
>>>   Target Report Var(aarch64_fix_a53_err835769) Init(2) Save
>>>   Workaround for ARM Cortex-A53 Erratum number 835769.
>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>> index 
>>> 35e8242af5fa4c52744fd2c3e2cfee0a617e22bb..8a3fab2964c9bb06c820766d284768751d63ac9a
>>>  100644
>>> --- a/gcc/doc/invoke.texi
>>> +++ b/gcc/doc/invoke.texi
>>> @@ -696,6 +696,7 @@ Objective-C and Objective-C++ Dialects}.
>>>   -msign-return-address=@var{scope} @gol
>>>   -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}
>>>   +@var{b-key}]|@var{bti} @gol
>>> +-mharden-sls=@var{none}|@var{all}|@var{retbr}|@var{blr} @gol
>>>   -march=@var{name}  -mcpu=@var{name}  -mtune=@var{name}  @gol
>>>   -moverride=@var{string}  -mverbose-cost-dump @gol
>>>   -mstack-protector-guard=@var{guard} 
>>> -mstack-protector-guard-reg=@var{sysreg} @gol
>>> @@ -17045,6 +17046,15 @@ functions.  The optional argument @samp{b-key} can 
>>> be used to sign the functions
>>>   with the B-key instead of the A-key.
>>>   @samp{bti} turns on branch target identification mechanism.
>>>   
>>> +@item -mharden-sls=@var{none}|@var{all}|@var{retbr}|@var{blr}
>>> +@opindex mharden-sls
>>> +Enable compiler hardening against straight line speculation (SLS).
>>> +There are two options for hardening against straight line speculation.
>>> +@samp{retbr} allows inserting speculation barriers after every
>>> +@samp{br} and @samp{ret} instruction.  While @samp{blr} enables replacing
>>> +@samp{blr} instructions with a @samp{bl} to a function stub.
>>> +@samp{all} enables all SLS hardening, while @samp{none} does not enable 
>>> any.
>> 
>> OK, so this is even more picky, sorry, but the syntax and description
>> imply to me that you can choose only one of the four options.  I think
>> it would be more accurate to say something like:
>> 
>> @item -mharden-sls=@var{opts}
>> @opindex mharden-sls
>> Enable compiler hardening against straight line speculation (SLS).
>> @var{opts} is a comma-separated list of the following options:
>> @table @samp
>> @item retbr
>> …
>> @item blr
>> …
>> @end table
>> In addition, @samp{-mharden-sls=all} enables all SLS hardening
>> while @samp{-mharden-sls=none} disables all SLS hardening.
>> 
>> (assuming the above behaviour change for “none”)
>> 
>> Thanks,
>> Richard
>> 
>
> Another "just to check": the same change should be made in the short 
> form right? (i.e. the hunk above is now `-mharden-sls=@var{opts}`)

Yeah.


Re: [Patch 1/3] aarch64: New Straight Line Speculation (SLS) mitigation flags

2020-06-23 Thread Matthew Malcomson

On 23/06/2020 16:48, Richard Sandiford wrote:

Matthew Malcomson  writes:

@@ -14466,6 +14466,81 @@ aarch64_validate_mcpu (const char *str, const struct 
processor **res,
return false;
  mfix-cortex-a53-835769
  Target Report Var(aarch64_fix_a53_err835769) Init(2) Save
  Workaround for ARM Cortex-A53 Erratum number 835769.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 
35e8242af5fa4c52744fd2c3e2cfee0a617e22bb..8a3fab2964c9bb06c820766d284768751d63ac9a
 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -696,6 +696,7 @@ Objective-C and Objective-C++ Dialects}.
  -msign-return-address=@var{scope} @gol
  -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}
  +@var{b-key}]|@var{bti} @gol
+-mharden-sls=@var{none}|@var{all}|@var{retbr}|@var{blr} @gol
  -march=@var{name}  -mcpu=@var{name}  -mtune=@var{name}  @gol
  -moverride=@var{string}  -mverbose-cost-dump @gol
  -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{sysreg} 
@gol
@@ -17045,6 +17046,15 @@ functions.  The optional argument @samp{b-key} can be 
used to sign the functions
  with the B-key instead of the A-key.
  @samp{bti} turns on branch target identification mechanism.
  
+@item -mharden-sls=@var{none}|@var{all}|@var{retbr}|@var{blr}

+@opindex mharden-sls
+Enable compiler hardening against straight line speculation (SLS).
+There are two options for hardening against straight line speculation.
+@samp{retbr} allows inserting speculation barriers after every
+@samp{br} and @samp{ret} instruction.  While @samp{blr} enables replacing
+@samp{blr} instructions with a @samp{bl} to a function stub.
+@samp{all} enables all SLS hardening, while @samp{none} does not enable any.


OK, so this is even more picky, sorry, but the syntax and description
imply to me that you can choose only one of the four options.  I think
it would be more accurate to say something like:

@item -mharden-sls=@var{opts}
@opindex mharden-sls
Enable compiler hardening against straight line speculation (SLS).
@var{opts} is a comma-separated list of the following options:
@table @samp
@item retbr
…
@item blr
…
@end table
In addition, @samp{-mharden-sls=all} enables all SLS hardening
while @samp{-mharden-sls=none} disables all SLS hardening.

(assuming the above behaviour change for “none”)

Thanks,
Richard



Another "just to check": the same change should be made in the short 
form right? (i.e. the hunk above is now `-mharden-sls=@var{opts}`)


Re: [Patch 1/3] aarch64: New Straight Line Speculation (SLS) mitigation flags

2020-06-23 Thread Richard Sandiford
Matthew Malcomson  writes:
> @@ -14466,6 +14466,81 @@ aarch64_validate_mcpu (const char *str, const struct 
> processor **res,
>return false;
>  }
>  
> +

Should just be one blank line here.

> +/* Straight line speculation indicators.  */
> +enum aarch64_sls_hardening_type
> +{
> +SLS_NONE = 0,
> +SLS_RETBR = 1,
> +SLS_BLR = 2,
> +SLS_ALL = 3,

Just indent by two spaces rather than four.

> +};
> +static enum aarch64_sls_hardening_type aarch64_sls_hardening;

Maybe easier to read with a line break here.

> +/* Return whether we should mitigatate Straight Line Speculation for the RET
> +   and BR instructions.  */
> +bool
> +aarch64_harden_sls_retbr_p (void)
> +{
> +  return aarch64_sls_hardening & SLS_RETBR;
> +}

…and here.

> +/* Return whether we should mitigatate Straight Line Speculation for the RET
> +   and BR instructions.  */
> +bool
> +aarch64_harden_sls_blr_p (void)
> +{
> +  return aarch64_sls_hardening & SLS_BLR;
> +}

Pasto: returns true for BLR speculation instead of RET + BR.

> +
> +/* As of yet we only allow setting these options globally, in the future we 
> may
> +   allow setting them per function.  */
> +static void
> +aarch64_validate_sls_mitigation (const char *const_str)
> +{
> +  char *str_root = xstrdup (const_str);
> +  char *token_save = NULL;
> +  char *str = NULL;
> +  int temp = SLS_NONE;
> +
> +  aarch64_sls_hardening = SLS_NONE;
> +  if (strcmp (str_root, "none") == 0)
> +goto finish;

In Clang I think this would override any previous option, so should
we set aarch64_sls_hardening to 0?

> +  if (strcmp (str_root, "all") == 0)
> +{
> +  aarch64_sls_hardening = SLS_ALL;
> +  goto finish;
> +}
> +
> +  str = strtok_r (str_root, ",", &token_save);
> +  if (!str)
> +{
> +  error ("invalid argument given to %<-mharden-sls=%>");
> +  goto finish;
> +}

I'm not particularly anti-goto, but in this case it looks simpler
to do the full-string comparisons on const_str and only duplicate
the string before the strtok_r.

> +  while (str)
> +{
> +  if (strcmp (str, "blr") == 0)
> + temp |= SLS_BLR;
> +  else if (strcmp (str, "retbr") == 0)
> + temp |= SLS_RETBR;
> +  else if (strcmp (str, "none") == 0 || strcmp (str, "all") == 0)
> + {
> +   error ("%<%s%> must be by itself for %<-mharden-sls=%>", str);
> +   break;
> + }
> +  else
> + {
> +   error ("invalid argument %<%s%> for %<-mharden-sls=%>", str);
> +   break;
> + }
> +  str = strtok_r (NULL, ",", &token_save);
> +}
> +  aarch64_sls_hardening = (aarch64_sls_hardening_type) temp;
> +finish:
> +  free (str_root);
> +  return;
> +}

Think it's more usual in gcc not to have explicit end-of-function void
returns.

>  /* Parses CONST_STR for branch protection features specified in
> aarch64_branch_protect_types, and set any global variables required.  
> Returns
> the parsing result and assigns LAST_STR to the last processed token from
> @@ -14710,6 +14785,9 @@ aarch64_override_options (void)
>selected_arch = NULL;
>selected_tune = NULL;
>  
> +  if (aarch64_harden_sls_string)
> +  aarch64_validate_sls_mitigation (aarch64_harden_sls_string);

Last line is indented two spaces too many.

> +
>if (aarch64_branch_protection_string)
>  aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
>  
> diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
> index 
> d99d14c137d8774d3c8dab860d475f68c01a2817..5170361fd5e5721e044d1664e522b2718f654b8e
>  100644
> --- a/gcc/config/aarch64/aarch64.opt
> +++ b/gcc/config/aarch64/aarch64.opt
> @@ -71,6 +71,10 @@ mgeneral-regs-only
>  Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Save
>  Generate code which uses only the general registers.
>  
> +mharden-sls=
> +Target RejectNegative Joined Var(aarch64_harden_sls_string)
> +Generate code to mitigate against straight line speculation.
> +
>  mfix-cortex-a53-835769
>  Target Report Var(aarch64_fix_a53_err835769) Init(2) Save
>  Workaround for ARM Cortex-A53 Erratum number 835769.
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 
> 35e8242af5fa4c52744fd2c3e2cfee0a617e22bb..8a3fab2964c9bb06c820766d284768751d63ac9a
>  100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -696,6 +696,7 @@ Objective-C and Objective-C++ Dialects}.
>  -msign-return-address=@var{scope} @gol
>  -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}
>  +@var{b-key}]|@var{bti} @gol
> +-mharden-sls=@var{none}|@var{all}|@var{retbr}|@var{blr} @gol
>  -march=@var{name}  -mcpu=@var{name}  -mtune=@var{name}  @gol
>  -moverride=@var{string}  -mverbose-cost-dump @gol
>  -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{sysreg} 
> @gol
> @@ -17045,6 +17046,15 @@ functions.  The optional argument @samp{b-key} can 
> be used to sign the functions
>  with the B-key instead of the A-key.
>  @samp{bti} turns on branch target identificati

[Patch 1/3] aarch64: New Straight Line Speculation (SLS) mitigation flags

2020-06-08 Thread Matthew Malcomson
Here we introduce the flags that will be used for straight line speculation.

The new flag introduced is `-mharden-sls=`.
This flag can take arguments of `none`, `all`, or a comma seperated list of one
or more of `retbr` or `blr`.
`none` indicates no special mitigation of the straight line speculation
vulnerability.
`all` requests all mitigations currently implemented.
`retbr` requests that the RET and BR instructions have a speculation barrier
inserted after them.
`blr` requests that BLR instructions are replaced by a BL to a function stub
using a BR with a speculation barrier after it.

Setting this on a per-function basis using attributes or the like is not
enabled, but may be in the future.

gcc/ChangeLog:

2020-06-08  Matthew Malcomson  

* config/aarch64/aarch64-protos.h (aarch64_harden_sls_retbr_p):
New.
(aarch64_harden_sls_blr_p): New.
* config/aarch64/aarch64.c (enum aarch64_sls_hardening_type):
New.
(aarch64_harden_sls_retbr_p): New.
(aarch64_harden_sls_blr_p): New.
(aarch64_validate_sls_mitigation): New.
(aarch64_override_options): Parse options for SLS mitigation.
* config/aarch64/aarch64.opt (-mharden-sls): New option.
* doc/invoke.texi: Document new option.



### Attachment also inlined for ease of reply###


diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 
9e43adb7db0373df6cc5ef1d2b22f217aca2aad2..8ca67d7e69edaf73c84f079e7e1c483009ad10c0
 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -780,4 +780,7 @@ extern const atomic_ool_names aarch64_ool_ldeor_names;
 
 tree aarch64_resolve_overloaded_builtin_general (location_t, tree, void *);
 
+extern bool aarch64_harden_sls_retbr_p (void);
+extern bool aarch64_harden_sls_blr_p (void);
+
 #endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 
e92c7e69fcb7a8689a8b7098b86ff050dc9ab78b..775f49991e5f599a843d3ef490b8cd044acfe78f
 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -14466,6 +14466,81 @@ aarch64_validate_mcpu (const char *str, const struct 
processor **res,
   return false;
 }
 
+
+/* Straight line speculation indicators.  */
+enum aarch64_sls_hardening_type
+{
+SLS_NONE = 0,
+SLS_RETBR = 1,
+SLS_BLR = 2,
+SLS_ALL = 3,
+};
+static enum aarch64_sls_hardening_type aarch64_sls_hardening;
+/* Return whether we should mitigatate Straight Line Speculation for the RET
+   and BR instructions.  */
+bool
+aarch64_harden_sls_retbr_p (void)
+{
+  return aarch64_sls_hardening & SLS_RETBR;
+}
+/* Return whether we should mitigatate Straight Line Speculation for the RET
+   and BR instructions.  */
+bool
+aarch64_harden_sls_blr_p (void)
+{
+  return aarch64_sls_hardening & SLS_BLR;
+}
+
+/* As of yet we only allow setting these options globally, in the future we may
+   allow setting them per function.  */
+static void
+aarch64_validate_sls_mitigation (const char *const_str)
+{
+  char *str_root = xstrdup (const_str);
+  char *token_save = NULL;
+  char *str = NULL;
+  int temp = SLS_NONE;
+
+  aarch64_sls_hardening = SLS_NONE;
+  if (strcmp (str_root, "none") == 0)
+goto finish;
+  if (strcmp (str_root, "all") == 0)
+{
+  aarch64_sls_hardening = SLS_ALL;
+  goto finish;
+}
+
+  str = strtok_r (str_root, ",", &token_save);
+  if (!str)
+{
+  error ("invalid argument given to %<-mharden-sls=%>");
+  goto finish;
+}
+
+  while (str)
+{
+  if (strcmp (str, "blr") == 0)
+   temp |= SLS_BLR;
+  else if (strcmp (str, "retbr") == 0)
+   temp |= SLS_RETBR;
+  else if (strcmp (str, "none") == 0 || strcmp (str, "all") == 0)
+   {
+ error ("%<%s%> must be by itself for %<-mharden-sls=%>", str);
+ break;
+   }
+  else
+   {
+ error ("invalid argument %<%s%> for %<-mharden-sls=%>", str);
+ break;
+   }
+  str = strtok_r (NULL, ",", &token_save);
+}
+  aarch64_sls_hardening = (aarch64_sls_hardening_type) temp;
+finish:
+  free (str_root);
+  return;
+}
+
 /* Parses CONST_STR for branch protection features specified in
aarch64_branch_protect_types, and set any global variables required.  
Returns
the parsing result and assigns LAST_STR to the last processed token from
@@ -14710,6 +14785,9 @@ aarch64_override_options (void)
   selected_arch = NULL;
   selected_tune = NULL;
 
+  if (aarch64_harden_sls_string)
+  aarch64_validate_sls_mitigation (aarch64_harden_sls_string);
+
   if (aarch64_branch_protection_string)
 aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
 
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 
d99d14c137d8774d3c8dab860d475f68c01a2817..5170361fd5e5721e044d1664e522b2718f654b8e
 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch6

Straight Line Speculation (SLS) mitigation.

2020-06-08 Thread Matthew Malcomson
Hi,

A new speculative cache side-channel vulnerability has been published at
the link below, named "straight-line speculation" (SLS in this patch series).
https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/downloads/straight-line-speculation
This vulnerability has been given CVE number CVE-2020-13844.

We have prepared some toolchain mitigations for this vulnerability.  These
mitigate against the RET, BR case and the BLR case mentioned in the linked
whitepaper.

The part of vulnerability relevant to these toolchain mitigations is as
follows:
Some processors may speculatively execute the instructions immediately
following what should be a change in control flow.  The examples we mitigate in
this patch series are the instructions RET (return), BR (indirect jump) and BLR
(indirect function call).
Where the speculative path contains a suitable code sequence, often described
by researchers as a "Spectre Revelation Gadget", such straight-line speculation
could lead to changes in the caches and similar structures that are indicative
of secrets, making those secrets vulnerable to revelation through timing
analysis.

The gist of the mitigation posted here is:

Every RET and BR instruction has a speculation barrier placed directly after
it.  These speculation barriers are not to be architecturally executed, so the
performance cost is expected to be low.

Each BLR instruction is replaced by a BL to a function stub consisting of a BR
instruction followed by a speculation barrier.
This alternate approach is used since the instructions directly after a BLR are
usually architecturally executed, and this approach ensures the speculation
barrier is off that architecturally executed path.
Arm has been unable to demonstrate straight line speculation past a BL or B
instruction, and so we believe the BL instruction can be used without a
barrier.

In summary, a
  RET
will be transformed to
  RET
  

While a
  BLR x
will be transformed to a
  BL __call_indirect_x
call, with __call_indirect_x being a thunk that looks like
__call_indirect_x:
  BR x
  


The patch series is structured as follows:
1) Introduce new command line arguments.
2) The RET/BR mitigation.
3) The BLR mitigation.

There are a few known places where this toolchain mitigation does not protect
against speculation places:
- Some accesses to thread-local variables use a code sequence including a BLR
  instruction.   This code sequence is part of the binary interface between
  compiler and linker. If this BLR instruction needs to be mitigated, it'd
  probably be best to do so in the linker.
  It seems that the code sequence for thread-local variable access is unlikely
  to lead to a Spectre Revalation Gadget.
- PLT stubs are produced by the linker, and each contain a BLR instruction.
  It seems that at most this could introduce one spectre relevation gadget
  after the last PLT stub.
- Use of BR, RET, or BLR instructions in assembly are not mitigated.
- Use of BR, RET, or BLR instructions in libraries and run-time library
  routines that are not recompiled with this toolchain mitigation are not
  mitigated.

N.b. patches with similar functionality are being posted to LLVM.

Thanks,
Matthew.


Entire patch series attached to cover letter.

all-patches.tar.gz
Description: application/gzip