Andrew Geissler | 595f630 | 2022-01-24 19:11:47 +0000 | [diff] [blame] | 1 | From 30461cf8dba3d3adb15a125e4da48800eb2b9b8f Mon Sep 17 00:00:00 2001 |
| 2 | From: Richard Earnshaw <rearnsha@arm.com> |
| 3 | Date: Fri, 18 Jun 2021 17:18:37 +0100 |
| 4 | Subject: [PATCH] arm: fix vlldm erratum for Armv8.1-m [PR102035] |
| 5 | |
| 6 | For Armv8.1-m we generate code that emits VLLDM directly and do not |
| 7 | rely on support code in the library, so emit the mitigation directly |
| 8 | as well, when required. In this case, we can use the compiler options |
| 9 | to determine when to apply the fix and when it is safe to omit it. |
| 10 | |
| 11 | gcc: |
| 12 | PR target/102035 |
| 13 | * config/arm/arm.md (attribute arch): Add fix_vlldm. |
| 14 | (arch_enabled): Use it. |
| 15 | * config/arm/vfp.md (lazy_store_multiple_insn): Add alternative to |
| 16 | use when erratum mitigation is needed. |
| 17 | |
| 18 | CVE: CVE-2021-35465 |
| 19 | Upstream-Status: Backport [https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=30461cf8dba3d3adb15a125e4da48800eb2b9b8f] |
| 20 | Signed-off-by: Pgowda <pgowda.cve@gmail.com> |
| 21 | |
| 22 | --- |
| 23 | gcc/config/arm/arm.md | 11 +++++++++-- |
| 24 | gcc/config/arm/vfp.md | 10 +++++++--- |
| 25 | 2 files changed, 16 insertions(+), 5 deletions(-) |
| 26 | |
| 27 | diff -upr a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md |
| 28 | --- a/gcc/config/arm/arm.md 2020-07-22 23:35:17.344384552 -0700 |
| 29 | +++ b/gcc/config/arm/arm.md 2021-11-11 20:33:58.431543947 -0800 |
| 30 | @@ -132,9 +132,12 @@ |
| 31 | ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6" |
| 32 | ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without |
| 33 | ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M |
| 34 | -; Baseline. This attribute is used to compute attribute "enabled", |
| 35 | +; Baseline. "fix_vlldm" is for fixing the v8-m/v8.1-m VLLDM erratum. |
| 36 | +; This attribute is used to compute attribute "enabled", |
| 37 | ; use type "any" to enable an alternative in all cases. |
| 38 | -(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon,mve" |
| 39 | +(define_attr "arch" "any, a, t, 32, t1, t2, v6,nov6, v6t2, \ |
| 40 | + v8mb, fix_vlldm, iwmmxt, iwmmxt2, armv6_or_vfpv3, \ |
| 41 | + neon, mve" |
| 42 | (const_string "any")) |
| 43 | |
| 44 | (define_attr "arch_enabled" "no,yes" |
| 45 | @@ -177,6 +180,10 @@ |
| 46 | (match_test "TARGET_THUMB1 && arm_arch8")) |
| 47 | (const_string "yes") |
| 48 | |
| 49 | + (and (eq_attr "arch" "fix_vlldm") |
| 50 | + (match_test "fix_vlldm")) |
| 51 | + (const_string "yes") |
| 52 | + |
| 53 | (and (eq_attr "arch" "iwmmxt2") |
| 54 | (match_test "TARGET_REALLY_IWMMXT2")) |
| 55 | (const_string "yes") |
| 56 | diff -upr a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md |
| 57 | --- a/gcc/config/arm/vfp.md 2020-07-22 23:35:17.356384684 -0700 |
| 58 | +++ b/gcc/config/arm/vfp.md 2021-11-11 20:33:58.431543947 -0800 |
| 59 | @@ -1703,12 +1703,15 @@ |
| 60 | (set_attr "type" "mov_reg")] |
| 61 | ) |
| 62 | |
| 63 | +;; Both this and the next instruction are treated by GCC in the same |
| 64 | +;; way as a blockage pattern. That's perhaps stronger than it needs |
| 65 | +;; to be, but we do not want accesses to the VFP register bank to be |
| 66 | +;; moved across either instruction. |
| 67 | + |
| 68 | (define_insn "lazy_store_multiple_insn" |
| 69 | - [(set (match_operand:SI 0 "s_register_operand" "+&rk") |
| 70 | - (post_dec:SI (match_dup 0))) |
| 71 | - (unspec_volatile [(const_int 0) |
| 72 | - (mem:SI (post_dec:SI (match_dup 0)))] |
| 73 | - VUNSPEC_VLSTM)] |
| 74 | + [(unspec_volatile |
| 75 | + [(mem:BLK (match_operand:SI 0 "s_register_operand" "rk"))] |
| 76 | + VUNSPEC_VLSTM)] |
| 77 | "use_cmse && reload_completed" |
| 78 | "vlstm%?\\t%0" |
| 79 | [(set_attr "predicable" "yes") |
| 80 | @@ -1716,14 +1719,16 @@ |
| 81 | ) |
| 82 | |
| 83 | (define_insn "lazy_load_multiple_insn" |
| 84 | - [(set (match_operand:SI 0 "s_register_operand" "+&rk") |
| 85 | - (post_inc:SI (match_dup 0))) |
| 86 | - (unspec_volatile:SI [(const_int 0) |
| 87 | - (mem:SI (match_dup 0))] |
| 88 | - VUNSPEC_VLLDM)] |
| 89 | + [(unspec_volatile |
| 90 | + [(mem:BLK (match_operand:SI 0 "s_register_operand" "rk,rk"))] |
| 91 | + VUNSPEC_VLLDM)] |
| 92 | "use_cmse && reload_completed" |
| 93 | - "vlldm%?\\t%0" |
| 94 | - [(set_attr "predicable" "yes") |
| 95 | + "@ |
| 96 | + vscclrm\\t{vpr}\;vlldm\\t%0 |
| 97 | + vlldm\\t%0" |
| 98 | + [(set_attr "arch" "fix_vlldm,*") |
| 99 | + (set_attr "predicable" "no") |
| 100 | + (set_attr "length" "8,4") |
| 101 | (set_attr "type" "load_4")] |
| 102 | ) |
| 103 | |