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 <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 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/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 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. + @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 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/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 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. + @item -msve-vector-bits=@var{bits} @opindex msve-vector-bits Specify the number of bits in an SVE vector register. This option only has