From 30461cf8dba3d3adb15a125e4da48800eb2b9b8f Mon Sep 17 00:00:00 2001
|
From: Richard Earnshaw <rearnsha@arm.com>
|
Date: Fri, 18 Jun 2021 17:18:37 +0100
|
Subject: [PATCH] arm: fix vlldm erratum for Armv8.1-m [PR102035]
|
|
For Armv8.1-m we generate code that emits VLLDM directly and do not
|
rely on support code in the library, so emit the mitigation directly
|
as well, when required. In this case, we can use the compiler options
|
to determine when to apply the fix and when it is safe to omit it.
|
|
gcc:
|
PR target/102035
|
* config/arm/arm.md (attribute arch): Add fix_vlldm.
|
(arch_enabled): Use it.
|
* config/arm/vfp.md (lazy_store_multiple_insn): Add alternative to
|
use when erratum mitigation is needed.
|
|
CVE: CVE-2021-35465
|
Upstream-Status: Backport[https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=30461cf8dba3d3adb15a125e4da48800eb2b9b8f]
|
Signed-off-by: Pgowda <pgowda.cve@gmail.com>
|
|
---
|
gcc/config/arm/arm.md | 11 +++++++++--
|
gcc/config/arm/vfp.md | 10 +++++++---
|
2 files changed, 16 insertions(+), 5 deletions(-)
|
|
diff -upr a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
|
--- a/gcc/config/arm/arm.md 2020-07-22 23:35:17.344384552 -0700
|
+++ b/gcc/config/arm/arm.md 2021-11-11 20:33:58.431543947 -0800
|
@@ -132,9 +132,12 @@
|
; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
|
; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
|
; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
|
-; Baseline. This attribute is used to compute attribute "enabled",
|
+; Baseline. "fix_vlldm" is for fixing the v8-m/v8.1-m VLLDM erratum.
|
+; This attribute is used to compute attribute "enabled",
|
; use type "any" to enable an alternative in all cases.
|
-(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon,mve"
|
+(define_attr "arch" "any, a, t, 32, t1, t2, v6,nov6, v6t2, \
|
+ v8mb, fix_vlldm, iwmmxt, iwmmxt2, armv6_or_vfpv3, \
|
+ neon, mve"
|
(const_string "any"))
|
|
(define_attr "arch_enabled" "no,yes"
|
@@ -177,6 +180,10 @@
|
(match_test "TARGET_THUMB1 && arm_arch8"))
|
(const_string "yes")
|
|
+ (and (eq_attr "arch" "fix_vlldm")
|
+ (match_test "fix_vlldm"))
|
+ (const_string "yes")
|
+
|
(and (eq_attr "arch" "iwmmxt2")
|
(match_test "TARGET_REALLY_IWMMXT2"))
|
(const_string "yes")
|
diff -upr a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
|
--- a/gcc/config/arm/vfp.md 2020-07-22 23:35:17.356384684 -0700
|
+++ b/gcc/config/arm/vfp.md 2021-11-11 20:33:58.431543947 -0800
|
@@ -1703,12 +1703,15 @@
|
(set_attr "type" "mov_reg")]
|
)
|
|
+;; Both this and the next instruction are treated by GCC in the same
|
+;; way as a blockage pattern. That's perhaps stronger than it needs
|
+;; to be, but we do not want accesses to the VFP register bank to be
|
+;; moved across either instruction.
|
+
|
(define_insn "lazy_store_multiple_insn"
|
- [(set (match_operand:SI 0 "s_register_operand" "+&rk")
|
- (post_dec:SI (match_dup 0)))
|
- (unspec_volatile [(const_int 0)
|
- (mem:SI (post_dec:SI (match_dup 0)))]
|
- VUNSPEC_VLSTM)]
|
+ [(unspec_volatile
|
+ [(mem:BLK (match_operand:SI 0 "s_register_operand" "rk"))]
|
+ VUNSPEC_VLSTM)]
|
"use_cmse && reload_completed"
|
"vlstm%?\\t%0"
|
[(set_attr "predicable" "yes")
|
@@ -1716,14 +1719,16 @@
|
)
|
|
(define_insn "lazy_load_multiple_insn"
|
- [(set (match_operand:SI 0 "s_register_operand" "+&rk")
|
- (post_inc:SI (match_dup 0)))
|
- (unspec_volatile:SI [(const_int 0)
|
- (mem:SI (match_dup 0))]
|
- VUNSPEC_VLLDM)]
|
+ [(unspec_volatile
|
+ [(mem:BLK (match_operand:SI 0 "s_register_operand" "rk,rk"))]
|
+ VUNSPEC_VLLDM)]
|
"use_cmse && reload_completed"
|
- "vlldm%?\\t%0"
|
- [(set_attr "predicable" "yes")
|
+ "@
|
+ vscclrm\\t{vpr}\;vlldm\\t%0
|
+ vlldm\\t%0"
|
+ [(set_attr "arch" "fix_vlldm,*")
|
+ (set_attr "predicable" "no")
|
+ (set_attr "length" "8,4")
|
(set_attr "type" "load_4")]
|
)
|
|