labrinea created this revision.
labrinea added reviewers: llvm-commits, momchil.velikov.
Herald added subscribers: dang, hiraditya, kristof.beyls.
labrinea requested review of this revision.
Herald added projects: clang, LLVM.
Herald added a subscriber: cfe-commits.

Recently a vulnerability issue is found in the implementation of VLLDM 
instruction in the Arm Cortex-M33, Cortex-M35P and Cortex-M55. If the VLLDM 
instruction is abandoned due to an exception when it is partially completed, it 
is possible for subsequent non-secure handler to access and modify the partial 
restored register values. This vulnerability is identified as CVE-2021-35465. 
The mitigation sequence varies between v8-m and v8.1-m as follows:

v8-m.main

  mrs        r5, control
  tst        r5, #8       /* CONTROL_S.SFPA */
  it         ne
  .inst.w    0xeeb00a40   /* vmovne s0, s0 */
  1:
  vlldm      sp           /* Lazy restore of d0-d16 and FPSCR. */

v8.1-m.main

  vscclrm    {vpr}        /* Clear VPR. */
  vlldm      sp           /* Lazy restore of d0-d16 and FPSCR. */

More details on 
https://developer.arm.com/support/arm-security-updates/vlldm-instruction-security-vulnerability


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D109157

Files:
  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:    vmov r7, r8, d1
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vmov r5, r6, d2
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vstr d3, [sp, #24]
+; CHECK-8M-FP-CVE-2021-35465-NEXT:    vstr d4, [sp, #32]
+; 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,12 @@
 
 #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"));
@@ -1530,6 +1536,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;
@@ -1550,6 +1561,7 @@
               .addReg(SaveReg1, RegState::Define)
               .addReg(SaveReg2, RegState::Define)
               .addReg(Reg)
+              .addReg(ARM::CPSR, RegState::ImplicitDefine)
               .add(predOps(ARMCC::AL));
         } else {
           NonclearedFPRegs.push_back(Reg);
@@ -1562,6 +1574,7 @@
           // Save the fp register to the normal registers
           BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRS), SaveReg)
               .addReg(Reg)
+              .addReg(ARM::CPSR, RegState::ImplicitDefine)
               .add(predOps(ARMCC::AL));
         } else {
           NonclearedFPRegs.push_back(Reg);
@@ -1576,14 +1589,49 @@
       BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTRD), Reg)
           .addReg(ARM::SP)
           .addImm((Reg - ARM::D0) * 2)
+          .addReg(ARM::CPSR, RegState::ImplicitDefine)
           .add(predOps(ARMCC::AL));
     else if (ARM::SPRRegClass.contains(Reg))
       BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTRS), Reg)
           .addReg(ARM::SP)
           .addImm(Reg - ARM::S0)
+          .addReg(ARM::CPSR, RegState::ImplicitDefine)
           .add(predOps(ARMCC::AL));
   }
 
+  if (EnableFix_CMSE_CVE_2021_35465) {
+    // Read the CONTROL register.
+    BuildMI(MBB, MBBI, DL, TII->get(ARM::t2MRS_M), ScratchReg)
+        .addImm(20)
+        .add(predOps(ARMCC::AL));
+    // Check bit 3 (SFPA).
+    BuildMI(MBB, MBBI, DL, TII->get(ARM::t2TSTri))
+        .addReg(ScratchReg)
+        .addImm(8)
+        .add(predOps(ARMCC::AL));
+    // If SFPA is clear jump over to VLLDM, otherwise execute an instruction
+    // which has no functional effect apart from causing context creation.
+    if (STI->hasFPRegs()) {
+      // vmovne s0, s0
+      BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVS))
+          .addReg(ARM::S0, RegState::Define)
+          .addReg(ARM::S0, RegState::Undef)
+          .addReg(ARM::CPSR, RegState::ImplicitDefine)
+          .add(predOps(ARMCC::NE)); // Expanded to IT block for Thumb
+    } else {
+      // In the absence of FPU we emit .inst.w 0xeeb00a40, which is defined as
+      // NOP if not executed, and so we don't need to mark S0 as kill/def.
+      // This also means that we need to explicitly emit the IT block, since
+      // Thumb2ITBlockPass will not recognise the instruction as conditional.
+      BuildMI(MBB, MBBI, DL, TII->get(ARM::t2IT))
+          .addImm(ARMCC::NE)
+          .addImm(8);
+      BuildMI(MBB, MBBI, DL, TII->get(ARM::INLINEASM))
+          .addExternalSymbol(".inst.w 0xeeb00a40")
+          .addImm(InlineAsm::Extra_HasSideEffects);
+    }
+  }
+
   // Lazy load fp regs from stack
   BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
       .addReg(ARM::SP)
@@ -1628,6 +1676,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,46 @@
+// Disable the fix
+//
+// 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
+//
+// CHECK-NOFIX: "-mllvm" "-arm-fix-cmse-cve-2021-35465=0"
+
+
+// Enable the fix
+//
+// 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 -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 %s -### \
+// RUN:   -mcmse 2>&1 | FileCheck %s --check-prefix=CHECK-FIX
+//
+// CHECK-FIX: "-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,31 @@
                     options::OPT_mno_implicit_float, true))
     CmdArgs.push_back("-no-implicit-float");
 
-  if (Args.getLastArg(options::OPT_mcmse))
+  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")) {
+        CmdArgs.push_back("-mllvm");
+        CmdArgs.push_back("-arm-fix-cmse-cve-2021-35465=1");
+      }
+    }
+  }
+
+  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");
+  }
 
   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)">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D109157: ... Alexandros Lamprineas via Phabricator via cfe-commits

Reply via email to