summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorTodd Mortimer <mortimer@cvs.openbsd.org>2021-09-01 13:37:15 +0000
committerTodd Mortimer <mortimer@cvs.openbsd.org>2021-09-01 13:37:15 +0000
commitfb522a9107a074a013dcedd326a78a65a4a2e1fd (patch)
tree3661ccf591c41f6e9b5797b4af0532e71d87568f /gnu
parent5ab0c4ee7316e4647235be809ad31209b550e5a7 (diff)
Add lfence after ret in retpoline thunk.
Recommended by AMD white paper Software Techniques for Managing Speculation on AMD Processors (9.17.20) mitigation V2-1. Pointed out by bluhm@. ok bluhm@ kettenis@
Diffstat (limited to 'gnu')
-rw-r--r--gnu/llvm/llvm/lib/Target/X86/X86IndirectThunks.cpp103
1 files changed, 5 insertions, 98 deletions
diff --git a/gnu/llvm/llvm/lib/Target/X86/X86IndirectThunks.cpp b/gnu/llvm/llvm/lib/Target/X86/X86IndirectThunks.cpp
index 36b9c3ccc95..ae26ed481c2 100644
--- a/gnu/llvm/llvm/lib/Target/X86/X86IndirectThunks.cpp
+++ b/gnu/llvm/llvm/lib/Target/X86/X86IndirectThunks.cpp
@@ -29,6 +29,7 @@
#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86Subtarget.h"
+#include "llvm/CodeGen/IndirectThunks.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -40,6 +41,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
using namespace llvm;
@@ -56,23 +58,6 @@ static const char LVIThunkNamePrefix[] = "__llvm_lvi_thunk_";
static const char R11LVIThunkName[] = "__llvm_lvi_thunk_r11";
namespace {
-template <typename Derived> class ThunkInserter {
- Derived &getDerived() { return *static_cast<Derived *>(this); }
-
-protected:
- bool InsertedThunks;
- void doInitialization(Module &M) {}
- void createThunkFunction(MachineModuleInfo &MMI, StringRef Name);
-
-public:
- void init(Module &M) {
- InsertedThunks = false;
- getDerived().doInitialization(M);
- }
- // return `true` if `MMI` or `MF` was modified
- bool run(MachineModuleInfo &MMI, MachineFunction &MF);
-};
-
struct RetpolineThunkInserter : ThunkInserter<RetpolineThunkInserter> {
const char *getThunkPrefix() { return RetpolineNamePrefix; }
bool mayUseThunk(const MachineFunction &MF) {
@@ -94,12 +79,9 @@ struct LVIThunkInserter : ThunkInserter<LVIThunkInserter> {
createThunkFunction(MMI, R11LVIThunkName);
}
void populateThunk(MachineFunction &MF) {
- // Grab the entry MBB and erase any other blocks. O0 codegen appears to
- // generate two bbs for the entry block.
+ assert (MF.size() == 1);
MachineBasicBlock *Entry = &MF.front();
Entry->clear();
- while (MF.size() > 1)
- MF.erase(std::next(MF.begin()));
// This code mitigates LVI by replacing each indirect call/jump with a
// direct call/jump to a thunk that looks like:
@@ -128,12 +110,6 @@ public:
bool doInitialization(Module &M) override;
bool runOnMachineFunction(MachineFunction &MF) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- MachineFunctionPass::getAnalysisUsage(AU);
- AU.addRequired<MachineModuleInfoWrapperPass>();
- AU.addPreserved<MachineModuleInfoWrapperPass>();
- }
-
private:
std::tuple<RetpolineThunkInserter, LVIThunkInserter> TIs;
@@ -224,12 +200,9 @@ void RetpolineThunkInserter::populateThunk(MachineFunction &MF) {
}
const TargetInstrInfo *TII = MF.getSubtarget<X86Subtarget>().getInstrInfo();
- // Grab the entry MBB and erase any other blocks. O0 codegen appears to
- // generate two bbs for the entry block.
+ assert (MF.size() == 1);
MachineBasicBlock *Entry = &MF.front();
Entry->clear();
- while (MF.size() > 1)
- MF.erase(std::next(MF.begin()));
MachineBasicBlock *CaptureSpec =
MF.CreateMachineBasicBlock(Entry->getBasicBlock());
@@ -277,73 +250,7 @@ void RetpolineThunkInserter::populateThunk(MachineFunction &MF) {
CallTarget->back().setPreInstrSymbol(MF, TargetSym);
BuildMI(CallTarget, DebugLoc(), TII->get(RetOpc));
-}
-
-template <typename Derived>
-void ThunkInserter<Derived>::createThunkFunction(MachineModuleInfo &MMI,
- StringRef Name) {
- assert(Name.startswith(getDerived().getThunkPrefix()) &&
- "Created a thunk with an unexpected prefix!");
-
- Module &M = const_cast<Module &>(*MMI.getModule());
- LLVMContext &Ctx = M.getContext();
- auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
- Function *F =
- Function::Create(Type, GlobalValue::LinkOnceODRLinkage, Name, &M);
- F->setVisibility(GlobalValue::HiddenVisibility);
- F->setComdat(M.getOrInsertComdat(Name));
-
- // Add Attributes so that we don't create a frame, unwind information, or
- // inline.
- AttrBuilder B;
- B.addAttribute(llvm::Attribute::NoUnwind);
- B.addAttribute(llvm::Attribute::Naked);
- F->addAttributes(llvm::AttributeList::FunctionIndex, B);
-
- // Populate our function a bit so that we can verify.
- BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
- IRBuilder<> Builder(Entry);
-
- Builder.CreateRetVoid();
-
- // MachineFunctions/MachineBasicBlocks aren't created automatically for the
- // IR-level constructs we already made. Create them and insert them into the
- // module.
- MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
- MachineBasicBlock *EntryMBB = MF.CreateMachineBasicBlock(Entry);
-
- // Insert EntryMBB into MF. It's not in the module until we do this.
- MF.insert(MF.end(), EntryMBB);
- // Set MF properties. We never use vregs...
- MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
-}
-
-template <typename Derived>
-bool ThunkInserter<Derived>::run(MachineModuleInfo &MMI, MachineFunction &MF) {
- // If MF is not a thunk, check to see if we need to insert a thunk.
- if (!MF.getName().startswith(getDerived().getThunkPrefix())) {
- // If we've already inserted a thunk, nothing else to do.
- if (InsertedThunks)
- return false;
-
- // Only add a thunk if one of the functions has the corresponding feature
- // enabled in its subtarget, and doesn't enable external thunks.
- // FIXME: Conditionalize on indirect calls so we don't emit a thunk when
- // nothing will end up calling it.
- // FIXME: It's a little silly to look at every function just to enumerate
- // the subtargets, but eventually we'll want to look at them for indirect
- // calls, so maybe this is OK.
- if (!getDerived().mayUseThunk(MF))
- return false;
-
- getDerived().insertThunks(MMI);
- InsertedThunks = true;
- return true;
- }
-
- // If this *is* a thunk function, we need to populate it with the correct MI.
- getDerived().populateThunk(MF);
- return true;
+ BuildMI(CallTarget, DebugLoc(), TII->get(X86::LFENCE));
}
FunctionPass *llvm::createX86IndirectThunksPass() {