llvm-project/llvm/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

183 lines
7.0 KiB
C++
Raw Normal View History

[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
//===-- X86SpeculativeExecutionSideEffectSuppression.cpp ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file contains the X86 implementation of the speculative execution side
/// effect suppression mitigation.
///
/// This must be used with the -mlvi-cfi flag in order to mitigate indirect
/// branches and returns.
//===----------------------------------------------------------------------===//
#include "X86.h"
#include "X86InstrInfo.h"
#include "X86Subtarget.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Pass.h"
#include "llvm/Target/TargetMachine.h"
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
using namespace llvm;
#define DEBUG_TYPE "x86-seses"
STATISTIC(NumLFENCEsInserted, "Number of lfence instructions inserted");
static cl::opt<bool> EnableSpeculativeExecutionSideEffectSuppression(
"x86-seses-enable-without-lvi-cfi",
cl::desc("Force enable speculative execution side effect suppression. "
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
"(Note: User must pass -mlvi-cfi in order to mitigate indirect "
"branches and returns.)"),
cl::init(false), cl::Hidden);
static cl::opt<bool> OneLFENCEPerBasicBlock(
"x86-seses-one-lfence-per-bb",
cl::desc(
"Omit all lfences other than the first to be placed in a basic block."),
cl::init(false), cl::Hidden);
static cl::opt<bool> OnlyLFENCENonConst(
"x86-seses-only-lfence-non-const",
cl::desc("Only lfence before groups of terminators where at least one "
"branch instruction has an input to the addressing mode that is a "
"register other than %rip."),
cl::init(false), cl::Hidden);
static cl::opt<bool>
OmitBranchLFENCEs("x86-seses-omit-branch-lfences",
cl::desc("Omit all lfences before branch instructions."),
cl::init(false), cl::Hidden);
namespace {
class X86SpeculativeExecutionSideEffectSuppression
: public MachineFunctionPass {
public:
X86SpeculativeExecutionSideEffectSuppression() : MachineFunctionPass(ID) {}
static char ID;
StringRef getPassName() const override {
return "X86 Speculative Execution Side Effect Suppression";
}
bool runOnMachineFunction(MachineFunction &MF) override;
};
} // namespace
char X86SpeculativeExecutionSideEffectSuppression::ID = 0;
// This function returns whether the passed instruction uses a memory addressing
// mode that is constant. We treat all memory addressing modes that read
// from a register that is not %rip as non-constant. Note that the use
// of the EFLAGS register results in an addressing mode being considered
// non-constant, therefore all JCC instructions will return false from this
// function since one of their operands will always be the EFLAGS register.
static bool hasConstantAddressingMode(const MachineInstr &MI) {
for (const MachineOperand &MO : MI.uses())
if (MO.isReg() && X86::RIP != MO.getReg())
return false;
return true;
}
bool X86SpeculativeExecutionSideEffectSuppression::runOnMachineFunction(
MachineFunction &MF) {
const auto &OptLevel = MF.getTarget().getOptLevel();
const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
// Check whether SESES needs to run as the fallback for LVI at O0, whether the
// user explicitly passed an SESES flag, or whether the SESES target feature
// was set.
if (!EnableSpeculativeExecutionSideEffectSuppression &&
!(Subtarget.useLVILoadHardening() && OptLevel == CodeGenOptLevel::None) &&
!Subtarget.useSpeculativeExecutionSideEffectSuppression())
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
return false;
LLVM_DEBUG(dbgs() << "********** " << getPassName() << " : " << MF.getName()
<< " **********\n");
bool Modified = false;
const X86InstrInfo *TII = Subtarget.getInstrInfo();
for (MachineBasicBlock &MBB : MF) {
MachineInstr *FirstTerminator = nullptr;
// Keep track of whether the previous instruction was an LFENCE to avoid
// adding redundant LFENCEs.
bool PrevInstIsLFENCE = false;
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
for (auto &MI : MBB) {
if (MI.getOpcode() == X86::LFENCE) {
PrevInstIsLFENCE = true;
continue;
}
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
// We want to put an LFENCE before any instruction that
// may load or store. This LFENCE is intended to avoid leaking any secret
// data due to a given load or store. This results in closing the cache
// and memory timing side channels. We will treat terminators that load
// or store separately.
if (MI.mayLoadOrStore() && !MI.isTerminator()) {
if (!PrevInstIsLFENCE) {
BuildMI(MBB, MI, DebugLoc(), TII->get(X86::LFENCE));
NumLFENCEsInserted++;
Modified = true;
}
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
if (OneLFENCEPerBasicBlock)
break;
}
// The following section will be LFENCEing before groups of terminators
// that include branches. This will close the branch prediction side
// channels since we will prevent code executing after misspeculation as
// a result of the LFENCEs placed with this logic.
// Keep track of the first terminator in a basic block since if we need
// to LFENCE the terminators in this basic block we must add the
// instruction before the first terminator in the basic block (as
// opposed to before the terminator that indicates an LFENCE is
// required). An example of why this is necessary is that the
// X86InstrInfo::analyzeBranch method assumes all terminators are grouped
// together and terminates it's analysis once the first non-termintor
// instruction is found.
if (MI.isTerminator() && FirstTerminator == nullptr)
FirstTerminator = &MI;
// Look for branch instructions that will require an LFENCE to be put
// before this basic block's terminators.
if (!MI.isBranch() || OmitBranchLFENCEs) {
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
// This isn't a branch or we're not putting LFENCEs before branches.
PrevInstIsLFENCE = false;
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
continue;
}
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
if (OnlyLFENCENonConst && hasConstantAddressingMode(MI)) {
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
// This is a branch, but it only has constant addressing mode and we're
// not adding LFENCEs before such branches.
PrevInstIsLFENCE = false;
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
continue;
}
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
// This branch requires adding an LFENCE.
if (!PrevInstIsLFENCE) {
assert(FirstTerminator && "Unknown terminator instruction");
BuildMI(MBB, FirstTerminator, DebugLoc(), TII->get(X86::LFENCE));
NumLFENCEsInserted++;
Modified = true;
}
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
break;
}
}
return Modified;
}
FunctionPass *llvm::createX86SpeculativeExecutionSideEffectSuppression() {
return new X86SpeculativeExecutionSideEffectSuppression();
}
INITIALIZE_PASS(X86SpeculativeExecutionSideEffectSuppression, "x86-seses",
"X86 Speculative Execution Side Effect Suppression", false,
[x86][seses] Introduce SESES pass for LVI This is an implementation of Speculative Execution Side Effect Suppression which is intended as a last resort mitigation against Load Value Injection, LVI, a newly disclosed speculative execution side channel vulnerability. One pager: https://software.intel.com/security-software-guidance/software-guidance/load-value-injection Deep dive: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection The mitigation consists of a compiler pass that inserts an LFENCE before each memory read instruction, memory write instruction, and the first branch instruction in a group of terminators at the end of a basic block. The goal is to prevent speculative execution, potentially based on misspeculated conditions and/or containing secret data, from leaking that data via side channels embedded in such instructions. This is something of a last-resort mitigation: it is expected to have extreme performance implications and it may not be a complete mitigation due to trying to enumerate side channels. In addition to the full version of the mitigation, this patch implements three flags to turn off part of the mitigation. These flags are disabled by default. The flags are not intended to result in a secure variant of the mitigation. The flags are intended to be used by users who would like to experiment with improving the performance of the mitigation. I ran benchmarks with each of these flags enabled in order to find if there was any room for further optimization of LFENCE placement with respect to LVI. Performance Testing Results When applying this mitigation to BoringSSL, we see the following results. These are a summary/aggregation of the performance changes when this mitigation is applied versus when no mitigation is applied. Fully Mitigated vs Baseline Geometric mean 0.071 (Note: This can be read as the ops/s of the mitigated program was 7.1% of the ops/s of the unmitigated program.) Minimum 0.041 Quartile 1 0.060 Median 0.063 Quartile 3 0.077 Maximum 0.230 Reviewed By: george.burgess.iv Differential Revision: https://reviews.llvm.org/D75939
2020-05-11 09:33:55 -07:00
false)