labrinea updated this revision to Diff 371083.
labrinea added a comment.

Changes in this revision:

- renamed fix_cve_2021_35465 to Fix_CVE_2021_35465
- added more Driver tests to cover the use of -mfix-cmse-cve-2021-35465 with 
-mno-fix-cmse-cve-2021-35465
- fixed code indentation


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109157/new/

https://reviews.llvm.org/D109157

Files:
  clang/docs/ClangCommandLineReference.rst
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/arm-cmse-cve-2021-35465.c
  llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
  llvm/test/CodeGen/ARM/cmse-cve-2021-35465-return.ll
  llvm/test/CodeGen/ARM/cmse-cve-2021-35465.ll

Index: llvm/test/CodeGen/ARM/cmse-cve-2021-35465.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/ARM/cmse-cve-2021-35465.ll
@@ -0,0 +1,101 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+;
+; RUN: llc %s -o - -mtriple=thumbv8m.main -mattr=+fp-armv8d16sp \
+; RUN:   -arm-fix-cmse-cve-2021-35465=1 | \
+; RUN:   FileCheck %s --check-prefix=CHECK-8M-FP-CVE-2021-35465
+;
+; RUN: llc %s -o - -mtriple=thumbv8m.main -mattr=-fpregs \
+; RUN:   -arm-fix-cmse-cve-2021-35465=1 | \
+; RUN:   FileCheck %s --check-prefix=CHECK-8M-NOFP-CVE-2021-35465
+;
+; RUN: llc %s -o - -mtriple=thumbv8.1m.main -mattr=+fp-armv8d16sp \
+; RUN:   -arm-fix-cmse-cve-2021-35465=1 | \
+; RUN:   FileCheck %s --check-prefix=CHECK-81M-CVE-2021-35465
+;
+; RUN: llc %s -o - -mtriple=thumbv8.1m.main -mattr=-fpregs \
+; RUN:   -arm-fix-cmse-cve-2021-35465=1 | \
+; RUN:   FileCheck %s --check-prefix=CHECK-81M-CVE-2021-35465
+
+
+define void @non_secure_call(void ()* %fptr) {
+; CHECK-8M-FP-CVE-2021-35465-LABEL: non_secure_call:
+; CHECK-8M-FP-CVE-2021-35465:       @ %bb.0:
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    push {r7, lr}
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    bic r0, r0, #1
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    sub sp, #136
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vlstm sp
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r1, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r2, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r3, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r4, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r5, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r6, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r7, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r8, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r9, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r10, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r11, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r12, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    msr apsr_nzcvq, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    blxns r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mrs r12, control
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    tst.w r12, #8
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    it ne
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmovne.f32 s0, s0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vlldm sp
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    add sp, #136
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    pop {r7, pc}
+;
+; CHECK-8M-NOFP-CVE-2021-35465-LABEL: non_secure_call:
+; CHECK-8M-NOFP-CVE-2021-35465:       @ %bb.0:
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    push {r7, lr}
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    bic r0, r0, #1
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    sub sp, #136
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    vlstm sp
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r1, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r2, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r3, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r4, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r5, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r6, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r7, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r8, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r9, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r10, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r11, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mov r12, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    msr apsr_nzcvq, r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    blxns r0
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    mrs r12, control
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    tst.w r12, #8
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    it ne
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    @APP
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    .inst.w 0xeeb00a40
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    @NO_APP
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    vlldm sp
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    add sp, #136
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; CHECK-8M-NOFP-CVE-2021-35465-NEXT:    pop {r7, pc}
+;
+; CHECK-81M-CVE-2021-35465-LABEL: non_secure_call:
+; CHECK-81M-CVE-2021-35465:       @ %bb.0:
+; CHECK-81M-CVE-2021-35465-NEXT:    push {r7, lr}
+; CHECK-81M-CVE-2021-35465-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; CHECK-81M-CVE-2021-35465-NEXT:    bic r0, r0, #1
+; CHECK-81M-CVE-2021-35465-NEXT:    sub sp, #136
+; CHECK-81M-CVE-2021-35465-NEXT:    vlstm sp
+; CHECK-81M-CVE-2021-35465-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; CHECK-81M-CVE-2021-35465-NEXT:    blxns r0
+; CHECK-81M-CVE-2021-35465-NEXT:    vscclrm {vpr}
+; CHECK-81M-CVE-2021-35465-NEXT:    vlldm sp
+; CHECK-81M-CVE-2021-35465-NEXT:    add sp, #136
+; CHECK-81M-CVE-2021-35465-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; CHECK-81M-CVE-2021-35465-NEXT:    pop {r7, pc}
+  call void %fptr() #0
+  ret void
+}
+
+attributes #0 = { "cmse_nonsecure_call" }
Index: llvm/test/CodeGen/ARM/cmse-cve-2021-35465-return.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/ARM/cmse-cve-2021-35465-return.ll
@@ -0,0 +1,69 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+;
+; RUN: llc %s -o - -mtriple=thumbv8m.main -mattr=+fp-armv8d16sp \
+; RUN:   -float-abi=hard -arm-fix-cmse-cve-2021-35465=1 | \
+; RUN:   FileCheck %s --check-prefix=CHECK-8M-FP-CVE-2021-35465
+
+%indirect = type { double, double, double, double, double, double, double, double }
+
+define %indirect @func(%indirect (float, i32, double, i32, float, i32, float, i32, double, double, double, double, float, float)* %fu, float %a, i32 %b, double %c, i32 %d, float %e, i32 %f, float %g, i32 %h, double %i, double %j, double %k, double %l, float %m, float %n) {
+; CHECK-8M-FP-CVE-2021-35465-LABEL: func:
+; CHECK-8M-FP-CVE-2021-35465:       @ %bb.0: @ %entry
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    push {r7, lr}
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov lr, r3
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r12, r0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r0, r1
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r1, r2
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    ldr r3, [sp, #8]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mov r2, lr
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    bic r12, r12, #1
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    sub sp, #136
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r4, s5
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r11, s0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r9, r10, d1
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r8, s1
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r7, s4
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r5, r6, d3
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vlstm sp
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov s0, r11
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov d1, r9, r10
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov s1, r8
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov s4, r7
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov d3, r5, r6
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov s5, r4
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vldr d4, [sp, #32]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vldr d5, [sp, #40]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vldr d6, [sp, #48]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vldr s14, [sp, #56]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    ldr r4, [sp, #64]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    bic r4, r4, #159
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    bic r4, r4, #4026531840
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmsr fpscr, r4
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    msr apsr_nzcvq, r12
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    blxns r12
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r9, r10, d0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vstr d3, [sp, #24]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r7, r8, d1
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vstr d4, [sp, #32]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r5, r6, d2
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vstr d5, [sp, #40]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vstr d6, [sp, #48]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vstr d7, [sp, #56]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    mrs r11, control
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    tst.w r11, #8
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    it ne
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmovne.f32 s0, s0
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vlldm sp
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov d0, r9, r10
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov d1, r7, r8
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov d2, r5, r6
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    add sp, #136
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    pop {r7, pc}
+entry:
+  %res = call %indirect %fu(float %a, i32 %b, double %c, i32 %d, float %e, i32 %f, float %g, i32 %h, double %i, double %j, double %k, double %l, float %m, float %n) #0
+  ret %indirect %res
+}
+
+attributes #0 = { "cmse_nonsecure_call" }
Index: llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -29,6 +29,10 @@
 
 #define DEBUG_TYPE "arm-pseudo"
 
+static cl::opt<bool> EnableFix_CMSE_CVE_2021_35465(
+    "arm-fix-cmse-cve-2021-35465", cl::Hidden,
+    cl::desc("Work around VLLDM erratum CVE-2021-35465"), cl::init(false));
+
 static cl::opt<bool>
 VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden,
                 cl::desc("Verify machine code after expanding ARM pseudos"));
@@ -1534,6 +1538,11 @@
     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
     SmallVectorImpl<unsigned> &AvailableRegs) {
 
+  // Keep a scratch register for the mitigation sequence.
+  unsigned ScratchReg = ARM::NoRegister;
+  if (EnableFix_CMSE_CVE_2021_35465)
+    ScratchReg = AvailableRegs.pop_back_val();
+
   // Use AvailableRegs to store the fp regs
   std::vector<std::tuple<unsigned, unsigned, unsigned>> ClearedFPRegs;
   std::vector<unsigned> NonclearedFPRegs;
@@ -1595,9 +1604,41 @@
 
   // Lazy load fp regs from stack.
   // This executes as NOP in the absence of floating-point support.
-  BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
-      .addReg(ARM::SP)
-      .add(predOps(ARMCC::AL));
+  MachineInstrBuilder VLLDM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
+                                  .addReg(ARM::SP)
+                                  .add(predOps(ARMCC::AL));
+
+  if (EnableFix_CMSE_CVE_2021_35465) {
+    auto Bundler = MIBundleBuilder(MBB, VLLDM);
+    // Read the CONTROL register.
+    Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2MRS_M))
+                       .addReg(ScratchReg)
+                       .addImm(20)
+                       .add(predOps(ARMCC::AL)));
+    // Check bit 3 (SFPA).
+    Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2TSTri))
+                       .addReg(ScratchReg)
+                       .addImm(8)
+                       .add(predOps(ARMCC::AL)));
+    // Emit the IT block.
+    Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2IT))
+                       .addImm(ARMCC::NE)
+                       .addImm(8));
+    // If SFPA is clear jump over to VLLDM, otherwise execute an instruction
+    // which has no functional effect apart from causing context creation:
+    // vmovne s0, s0. In the absence of FPU we emit .inst.w 0xeeb00a40,
+    // which is defined as NOP if not executed.
+    if (STI->hasFPRegs())
+      Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::VMOVS))
+                         .addReg(ARM::S0, RegState::Define)
+                         .addReg(ARM::S0, RegState::Undef)
+                         .add(predOps(ARMCC::NE)));
+    else
+      Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::INLINEASM))
+                         .addExternalSymbol(".inst.w 0xeeb00a40")
+                         .addImm(InlineAsm::Extra_HasSideEffects));
+    finalizeBundle(MBB, Bundler.begin(), Bundler.end());
+  }
 
   // Restore all FP registers via normal registers
   for (const auto &Regs : ClearedFPRegs) {
@@ -1638,6 +1679,12 @@
     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
     SmallVectorImpl<unsigned> &AvailableRegs) {
   if (!definesOrUsesFPReg(*MBBI)) {
+    if (EnableFix_CMSE_CVE_2021_35465) {
+      BuildMI(MBB, MBBI, DL, TII->get(ARM::VSCCLRMS))
+          .add(predOps(ARMCC::AL))
+          .addReg(ARM::VPR, RegState::Define);
+    }
+
     // Load FP registers from stack.
     BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
         .addReg(ARM::SP)
Index: clang/test/Driver/arm-cmse-cve-2021-35465.c
===================================================================
--- /dev/null
+++ clang/test/Driver/arm-cmse-cve-2021-35465.c
@@ -0,0 +1,68 @@
+// Disable the fix - check that we don't enable it by default before disabling
+//
+// RUN: %clang --target=arm-arm-none-eabi -march=armv8-m.main %s -### \
+// RUN:   -mcmse -mno-fix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-NOFIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -march=armv8.1-m.main %s -### \
+// RUN:   -mcmse -mno-fix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-NOFIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -march=armv8-m.main %s -### \
+// RUN:   -mcmse -mfix-cmse-cve-2021-35465 -mno-fix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-NOFIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -mcpu=cortex-m33 %s -### \
+// RUN:   -mcmse -mno-fix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-NOFIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -mcpu=cortex-m35p+nofp %s -### \
+// RUN:   -mcmse -mno-fix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-NOFIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -mcpu=cortex-m55 %s -### \
+// RUN:   -mcmse -mno-fix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-NOFIX
+//
+// CHECK-NOFIX-NOT: "-mllvm" "-arm-fix-cmse-cve-2021-35465=1"
+// CHECK-NOFIX: "-mllvm" "-arm-fix-cmse-cve-2021-35465=0"
+
+
+// Enable the fix - check that we pass the option to enable it just once
+//
+// RUN: %clang --target=arm-arm-none-eabi -march=armv8-m.main %s -### \
+// RUN:   -mcmse -mfix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-FIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -march=armv8.1-m.main %s -### \
+// RUN:   -mcmse -mfix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-FIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -march=armv8-m.main %s -### \
+// RUN:   -mcmse -mno-fix-cmse-cve-2021-35465 -mfix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-FIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -mcpu=cortex-m33+nofp %s -### \
+// RUN:   -mcmse 2>&1 | FileCheck %s --check-prefix=CHECK-FIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -mcpu=cortex-m35p %s -### \
+// RUN:   -mcmse 2>&1 | FileCheck %s --check-prefix=CHECK-FIX
+//
+// RUN: %clang --target=arm-arm-none-eabi -mcpu=cortex-m55+nofp %s -### \
+// RUN:   -mcmse 2>&1 | FileCheck %s --check-prefix=CHECK-FIX
+//
+// CHECK-FIX: "-mllvm" "-arm-fix-cmse-cve-2021-35465=1"
+// CHECK-FIX-NOT: "-mllvm" "-arm-fix-cmse-cve-2021-35465=1"
+
+
+// Diagnose the option when used without -mcmse
+//
+// RUN: %clang --target=arm-arm-none-eabi -march=armv8-m.main %s -### \
+// RUN:   -mfix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-DIAG
+//
+// RUN: %clang --target=arm-arm-none-eabi -march=armv8.1-m.main %s -### \
+// RUN:   -mno-fix-cmse-cve-2021-35465 2>&1 |\
+// RUN:   FileCheck %s --check-prefix=CHECK-DIAG
+//
+// CHECK-DIAG: error: option 'm{{.*}}fix-cmse-cve-2021-35465' cannot be specified without '-mcmse'
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1643,8 +1643,33 @@
                     options::OPT_mno_implicit_float, true))
     CmdArgs.push_back("-no-implicit-float");
 
-  if (Args.getLastArg(options::OPT_mcmse))
+  bool Fix_CVE_2021_35465 = false;
+  if (Args.getLastArg(options::OPT_mcmse)) {
     CmdArgs.push_back("-mcmse");
+    if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+      StringRef CPU = A->getValue();
+      if (CPU.startswith("cortex-m33") || CPU.startswith("cortex-m35p") ||
+          CPU.startswith("cortex-m55")) {
+        Fix_CVE_2021_35465 = true;
+      }
+    }
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mfix_cmse_cve_2021_35465,
+                               options::OPT_mno_fix_cmse_cve_2021_35465)) {
+    if (!Args.hasArg(options::OPT_mcmse))
+      getToolChain().getDriver().Diag(diag::err_opt_not_valid_without_opt)
+          << A->getOption().getName() << "-mcmse";
+
+    CmdArgs.push_back("-mllvm");
+    if (A->getOption().matches(options::OPT_mfix_cmse_cve_2021_35465))
+      CmdArgs.push_back("-arm-fix-cmse-cve-2021-35465=1");
+    else
+      CmdArgs.push_back("-arm-fix-cmse-cve-2021-35465=0");
+  } else if (Fix_CVE_2021_35465) {
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back("-arm-fix-cmse-cve-2021-35465=1");
+  }
 
   AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
 }
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -3269,6 +3269,12 @@
 
 def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_Group>,
   HelpText<"Generate code which only uses the general purpose registers (AArch64/x86 only)">;
+def mfix_cmse_cve_2021_35465 : Flag<["-"], "mfix-cmse-cve-2021-35465">,
+  Group<m_arm_Features_Group>,
+  HelpText<"Work around VLLDM erratum CVE-2021-35465 (Arm only)">;
+def mno_fix_cmse_cve_2021_35465 : Flag<["-"], "mno-fix-cmse-cve-2021-35465">,
+  Group<m_arm_Features_Group>,
+  HelpText<"Don't work around VLLDM erratum CVE-2021-35465 (Arm only)">;
 def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
   Group<m_aarch64_Features_Group>,
   HelpText<"Workaround Cortex-A53 erratum 835769 (AArch64 only)">;
Index: clang/docs/ClangCommandLineReference.rst
===================================================================
--- clang/docs/ClangCommandLineReference.rst
+++ clang/docs/ClangCommandLineReference.rst
@@ -3228,6 +3228,10 @@
 
 Allow use of CMSE (Armv8-M Security Extensions)
 
+.. option:: -mfix-cmse-cve-2021-35465, -mno-fix-cmse-cve-2021-35465
+
+Enable the cve-2021-35465 security vulnerability mitigation (ARM only). On by default when targeting the affected CPUs: Cortex-M33, Cortex-M35P and Cortex-M55.
+
 .. option:: -mexecute-only, -mno-execute-only, -mpure-code
 
 Disallow generation of data access to code sections (ARM only)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to