Skip to content

Commit c3a8938

Browse files
author
Simon Dardis
committed
Backporting 325651::
------------------------------------------------------------------------ r325651 | sdardis | 2018-02-21 00:05:05 +0000 (Wed, 21 Feb 2018) | 34 lines [mips] Spectre variant two mitigation for MIPSR2 This patch provides mitigation for CVE-2017-5715, Spectre variant two, which affects the P5600 and P6600. It provides the option -mindirect-jump=hazard, which instructs the LLVM backend to replace indirect branches with their hazard barrier variants. This option is accepted when targeting MIPS revision two or later. The migitation strategy suggested by MIPS for these processors is to use two hazard barrier instructions. 'jalr.hb' and 'jr.hb' are hazard barrier variants of the 'jalr' and 'jr' instructions respectively. These instructions impede the execution of instruction stream until architecturally defined hazards (changes to the instruction stream, privileged registers which may affect execution) are cleared. These instructions in MIPS' designs are not speculated past. These instructions are used with the option -mindirect-jump=hazard when branching indirectly and for indirect function calls. These instructions are defined by the MIPS32R2 ISA, so this mitigation method is not compatible with processors which implement an earlier revision of the MIPS ISA. Implementation note: I've opted to provide this as an -mindirect-jump={hazard,...} style option in case alternative mitigation methods are required for other implementations of the MIPS ISA in future, e.g. retpoline style solutions. Reviewers: atanasyan Differential Revision: https://reviews.llvm.org/D43487 ------------------------------------------------------------------------ llvm-svn: 327755
1 parent 64778dc commit c3a8938

File tree

6 files changed

+58
-1
lines changed

6 files changed

+58
-1
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,10 @@ def warn_target_unsupported_nanlegacy : Warning<
280280
def warn_target_unsupported_compact_branches : Warning<
281281
"ignoring '-mcompact-branches=' option because the '%0' architecture does not"
282282
" support it">, InGroup<UnsupportedCB>;
283+
def err_drv_unsupported_indirect_jump_opt : Error<
284+
"'-mindirect-jump=%0' is unsupported with the '%1' architecture">;
285+
def err_drv_unknown_indirect_jump_opt : Error<
286+
"unknown '-mindirect-jump=' option '%0'">;
283287

284288
def warn_drv_unable_to_find_directory_expected : Warning<
285289
"unable to find %0 directory, expected to be in '%1'">,

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,9 @@ def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">, Group<m_Group>;
20162016
def mno_check_zero_division : Flag<["-"], "mno-check-zero-division">,
20172017
Group<m_Group>;
20182018
def mcompact_branches_EQ : Joined<["-"], "mcompact-branches=">, Group<m_Group>;
2019+
def mindirect_jump_EQ : Joined<["-"], "mindirect-jump=">,
2020+
Group<m_Group>,
2021+
HelpText<"Change indirect jump instructions to inhibit speculation">;
20192022
def mdsp : Flag<["-"], "mdsp">, Group<m_Group>;
20202023
def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_Group>;
20212024
def mdspr2 : Flag<["-"], "mdspr2">, Group<m_Group>;

clang/lib/Basic/Targets.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8065,6 +8065,7 @@ class MipsTargetInfo : public TargetInfo {
80658065
} DspRev;
80668066
bool HasMSA;
80678067
bool DisableMadd4;
8068+
bool UseIndirectJumpHazard;
80688069

80698070
protected:
80708071
bool HasFP64;
@@ -8075,7 +8076,8 @@ class MipsTargetInfo : public TargetInfo {
80758076
: TargetInfo(Triple), IsMips16(false), IsMicromips(false),
80768077
IsNan2008(false), IsSingleFloat(false), IsNoABICalls(false),
80778078
CanUseBSDABICalls(false), FloatABI(HardFloat), DspRev(NoDSP),
8078-
HasMSA(false), DisableMadd4(false), HasFP64(false) {
8079+
HasMSA(false), DisableMadd4(false), UseIndirectJumpHazard(false),
8080+
HasFP64(false) {
80798081
TheCXXABI.set(TargetCXXABI::GenericMIPS);
80808082

80818083
setABI((getTriple().getArch() == llvm::Triple::mips ||
@@ -8498,6 +8500,8 @@ class MipsTargetInfo : public TargetInfo {
84988500
IsNan2008 = false;
84998501
else if (Feature == "+noabicalls")
85008502
IsNoABICalls = true;
8503+
else if (Feature == "+use-indirect-jump-hazard")
8504+
UseIndirectJumpHazard = true;
85018505
}
85028506

85038507
setDataLayout();

clang/lib/Driver/ToolChains/Arch/Mips.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,28 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
302302
AddTargetFeature(Args, Features, options::OPT_mlong_calls,
303303
options::OPT_mno_long_calls, "long-calls");
304304
AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt,"mt");
305+
306+
if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
307+
StringRef Val = StringRef(A->getValue());
308+
if (Val == "hazard") {
309+
Arg *B =
310+
Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
311+
Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
312+
313+
if (B && B->getOption().matches(options::OPT_mmicromips))
314+
D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
315+
<< "hazard" << "micromips";
316+
else if (C && C->getOption().matches(options::OPT_mips16))
317+
D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
318+
<< "hazard" << "mips16";
319+
else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
320+
Features.push_back("+use-indirect-jump-hazard");
321+
else
322+
D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
323+
<< "hazard" << CPUName;
324+
} else
325+
D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
326+
}
305327
}
306328

307329
mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
@@ -327,6 +349,23 @@ mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
327349
.Default(NanLegacy);
328350
}
329351

352+
bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
353+
// Supporting the hazard barrier method of dealing with indirect
354+
// jumps requires MIPSR2 support.
355+
return llvm::StringSwitch<bool>(CPU)
356+
.Case("mips32r2", true)
357+
.Case("mips32r3", true)
358+
.Case("mips32r5", true)
359+
.Case("mips32r6", true)
360+
.Case("mips64r2", true)
361+
.Case("mips64r3", true)
362+
.Case("mips64r5", true)
363+
.Case("mips64r6", true)
364+
.Case("octeon", true)
365+
.Case("p5600", true)
366+
.Default(false);
367+
}
368+
330369
bool mips::hasCompactBranches(StringRef &CPU) {
331370
// mips32r6 and mips64r6 have compact branches.
332371
return llvm::StringSwitch<bool>(CPU)

clang/lib/Driver/ToolChains/Arch/Mips.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ bool isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
5353
bool shouldUseFPXX(const llvm::opt::ArgList &Args, const llvm::Triple &Triple,
5454
StringRef CPUName, StringRef ABIName,
5555
mips::FloatABI FloatABI);
56+
bool supportsIndirectJumpHazardBarrier(StringRef &CPU);
5657

5758
} // end namespace mips
5859
} // end namespace target

clang/test/Driver/mips-features.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,9 @@
270270
// LONG-CALLS-ON: "-target-feature" "+long-calls"
271271
// LONG-CALLS-OFF: "-target-feature" "-long-calls"
272272
// LONG-CALLS-DEF-NOT: "long-calls"
273+
274+
// -mindirect-jump=hazard
275+
// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \
276+
// RUN: -mindirect-jump=hazard 2>&1 \
277+
// RUN: | FileCheck --check-prefix=INDIRECT-BH %s
278+
// INDIRECT-BH: "-target-feature" "+use-indirect-jump-hazard"

0 commit comments

Comments
 (0)