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 <matthew.malcom...@arm.com> * 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/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 98cc0f2f0de1d89928d98edcb2f2fa99f040f195..fd71f7c79019b681008d08284eff2878790b7ffa 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -698,6 +698,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{opts} @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 @@ -17367,6 +17368,17 @@ 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{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. + @item -msve-vector-bits=@var{bits} @opindex msve-vector-bits Specify the number of bits in an SVE vector register. This option only has
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/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 98cc0f2f0de1d89928d98edcb2f2fa99f040f195..fd71f7c79019b681008d08284eff2878790b7ffa 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -698,6 +698,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{opts} @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 @@ -17367,6 +17368,17 @@ 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{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. + @item -msve-vector-bits=@var{bits} @opindex msve-vector-bits Specify the number of bits in an SVE vector register. This option only has