diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3269,6 +3269,12 @@ def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, 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, + 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, + HelpText<"Don't work around VLLDM erratum CVE-2021-35465 (Arm only)">; def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">, Group, HelpText<"Workaround Cortex-A53 erratum 835769 (AArch64 only)">; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/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); } diff --git a/clang/test/Driver/arm-cmse-cve-2021-35465.c b/clang/test/Driver/arm-cmse-cve-2021-35465.c new file mode 100644 --- /dev/null +++ b/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' diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -29,6 +29,12 @@ #define DEBUG_TYPE "arm-pseudo" +static cl::opt 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 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 &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> ClearedFPRegs; std::vector 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 &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) diff --git a/llvm/test/CodeGen/ARM/cmse-cve-2021-35465-return.ll b/llvm/test/CodeGen/ARM/cmse-cve-2021-35465-return.ll new file mode 100644 --- /dev/null +++ b/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" } diff --git a/llvm/test/CodeGen/ARM/cmse-cve-2021-35465.ll b/llvm/test/CodeGen/ARM/cmse-cve-2021-35465.ll new file mode 100644 --- /dev/null +++ b/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" }