Skip to content

Commit

Permalink
[ARM] Pass for Cortex-A57 and Cortex-A72 Fused AES Erratum
Browse files Browse the repository at this point in the history
This adds a late Machine Pass to work around a Cortex CPU Erratum
affecting Cortex-A57 and Cortex-A72:
- Cortex-A57 Erratum 1742098
- Cortex-A72 Erratum 1655431

The pass inserts instructions to make the inputs to the fused AES
instruction pairs no longer trigger the erratum. Here the pass errs on
the side of caution, inserting the instructions wherever we cannot prove
that the inputs came from a safe instruction.

The pass is used:
- for Cortex-A57 and Cortex-A72,
- for "generic" cores (which are used when using `-march=`),
- when the user specifies `-mfix-cortex-a57-aes-1742098` or
  `mfix-cortex-a72-aes-1655431` in the command-line arguments to clang.

Reviewed By: dmgreen, simon_tatham

Differential Revision: https://reviews.llvm.org/D119720
  • Loading branch information
lenary committed May 13, 2022
1 parent 7deed49 commit 3a24df9
Show file tree
Hide file tree
Showing 10 changed files with 627 additions and 3 deletions.
14 changes: 14 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3451,6 +3451,20 @@ def mfix_cmse_cve_2021_35465 : Flag<["-"], "mfix-cmse-cve-2021-35465">,
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_a57_aes_1742098 : Flag<["-"], "mfix-cortex-a57-aes-1742098">,
Group<m_arm_Features_Group>,
HelpText<"Work around Cortex-A57 Erratum 1742098 (ARM only)">;
def mno_fix_cortex_a57_aes_1742098 : Flag<["-"], "mno-fix-cortex-a57-aes-1742098">,
Group<m_arm_Features_Group>,
HelpText<"Don't work around Cortex-A57 Erratum 1742098 (ARM only)">;
def mfix_cortex_a72_aes_1655431 : Flag<["-"], "mfix-cortex-a72-aes-1655431">,
Group<m_arm_Features_Group>,
HelpText<"Work around Cortex-A72 Erratum 1655431 (ARM only)">,
Alias<mfix_cortex_a57_aes_1742098>;
def mno_fix_cortex_a72_aes_1655431 : Flag<["-"], "mno-fix-cortex-a72-aes-1655431">,
Group<m_arm_Features_Group>,
HelpText<"Don't work around Cortex-A72 Erratum 1655431 (ARM only)">,
Alias<mno_fix_cortex_a57_aes_1742098>;
def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
Group<m_aarch64_Features_Group>,
HelpText<"Workaround Cortex-A53 erratum 835769 (AArch64 only)">;
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,16 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
Features.push_back("-fix-cmse-cve-2021-35465");
}

// This also handles the -m(no-)fix-cortex-a72-1655431 arguments via aliases.
if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a57_aes_1742098,
options::OPT_mno_fix_cortex_a57_aes_1742098)) {
if (A->getOption().matches(options::OPT_mfix_cortex_a57_aes_1742098)) {
Features.push_back("+fix-cortex-a57-aes-1742098");
} else {
Features.push_back("-fix-cortex-a57-aes-1742098");
}
}

// Look for the last occurrence of -mlong-calls or -mno-long-calls. If
// neither options are specified, see if we are compiling for kernel/kext and
// decide whether to pass "+long-calls" based on the OS and its version.
Expand Down
25 changes: 25 additions & 0 deletions clang/test/Driver/arm-fix-cortex-a57-aes-1742098.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %clang -### %s -target arm-none-none-eabi -march=armv8a -mfix-cortex-a57-aes-1742098 2>&1 | FileCheck %s --check-prefix=FIX
// RUN: %clang -### %s -target arm-none-none-eabi -march=armv8a -mno-fix-cortex-a57-aes-1742098 2>&1 | FileCheck %s --check-prefix=NO-FIX

// RUN: %clang -### %s -target arm-none-none-eabi -march=armv8a -mfix-cortex-a72-aes-1655431 2>&1 | FileCheck %s --check-prefix=FIX
// RUN: %clang -### %s -target arm-none-none-eabi -march=armv8a -mno-fix-cortex-a72-aes-1655431 2>&1 | FileCheck %s --check-prefix=NO-FIX

// RUN: %clang -### %s -target arm-none-none-eabi -march=armv8a 2>&1 | FileCheck %s --check-prefix=UNSPEC
// RUN: %clang -### %s -target arm-none-none-eabi -march=armv8a 2>&1 | FileCheck %s --check-prefix=UNSPEC

// This test checks that "-m(no-)fix-cortex-a57-aes-1742098" and
// "-m(no-)fix-cortex-a72-aes-1655431" cause the "fix-cortex-a57-aes-1742098"
// target feature to be passed to `clang -cc1`.
//
// This feature is also enabled in the backend for the two affected CPUs and the
// "generic" cpu (used when only specifying -march), but that won't show up on
// the `clang -cc1` command line.
//
// We do not check whether this option is correctly specified for the CPU: users
// can specify the "-mfix-cortex-a57-aes-1742098" option with "-mcpu=cortex-a72"
// and vice-versa, and will still get the fix, as the target feature and the fix
// is the same in both cases.

// FIX: "-target-feature" "+fix-cortex-a57-aes-1742098"
// NO-FIX: "-target-feature" "-fix-cortex-a57-aes-1742098"
// UNSPEC-NOT: "-target-feature" "{[+-]}fix-cortex-a57-aes-1742098"
2 changes: 2 additions & 0 deletions llvm/lib/Target/ARM/ARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Pass *createMVEGatherScatterLoweringPass();
FunctionPass *createARMSLSHardeningPass();
FunctionPass *createARMIndirectThunks();
Pass *createMVELaneInterleavingPass();
FunctionPass *createARMFixCortexA57AES1742098Pass();

void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
ARMAsmPrinter &AP);
Expand All @@ -77,6 +78,7 @@ void initializeMVETailPredicationPass(PassRegistry &);
void initializeMVEGatherScatterLoweringPass(PassRegistry &);
void initializeARMSLSHardeningPass(PassRegistry &);
void initializeMVELaneInterleavingPass(PassRegistry &);
void initializeARMFixCortexA57AES1742098Pass(PassRegistry &);

} // end namespace llvm

Expand Down
12 changes: 9 additions & 3 deletions llvm/lib/Target/ARM/ARM.td
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,10 @@ def FeatureNoBTIAtReturnTwice : SubtargetFeature<"no-bti-at-return-twice",
"Don't place a BTI instruction "
"after a return-twice">;

def FeatureFixCortexA57AES1742098 : SubtargetFeature<"fix-cortex-a57-aes-1742098",
"FixCortexA57AES1742098", "true",
"Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)">;

//===----------------------------------------------------------------------===//
// ARM architecture class
//
Expand Down Expand Up @@ -1157,7 +1161,7 @@ include "ARMScheduleM7.td"
// ARM processors
//
// Dummy CPU, used to target architectures
def : ProcessorModel<"generic", CortexA8Model, []>;
def : ProcessorModel<"generic", CortexA8Model, [FeatureFixCortexA57AES1742098]>;

// FIXME: Several processors below are not using their own scheduler
// model, but one of similar/previous processor. These should be fixed.
Expand Down Expand Up @@ -1467,13 +1471,15 @@ def : ProcessorModel<"cortex-a57", CortexA57Model, [ARMv8a, ProcA57,
FeatureCRC,
FeatureFPAO,
FeatureAvoidPartialCPSR,
FeatureCheapPredicableCPSR]>;
FeatureCheapPredicableCPSR,
FeatureFixCortexA57AES1742098]>;

def : ProcessorModel<"cortex-a72", CortexA57Model, [ARMv8a, ProcA72,
FeatureHWDivThumb,
FeatureHWDivARM,
FeatureCrypto,
FeatureCRC]>;
FeatureCRC,
FeatureFixCortexA57AES1742098]>;

def : ProcNoItin<"cortex-a73", [ARMv8a, ProcA73,
FeatureHWDivThumb,
Expand Down
Loading

0 comments on commit 3a24df9

Please sign in to comment.