23 |
23 |
24 |
24 |
25 |
25 |
26 package org.graalvm.compiler.core.amd64; |
26 package org.graalvm.compiler.core.amd64; |
27 |
27 |
28 import static org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder.Options.MitigateSpeculativeExecutionAttacks; |
|
29 |
|
30 import org.graalvm.compiler.core.gen.NodeLIRBuilder; |
28 import org.graalvm.compiler.core.gen.NodeLIRBuilder; |
31 import org.graalvm.compiler.debug.GraalError; |
29 import org.graalvm.compiler.debug.GraalError; |
32 import org.graalvm.compiler.lir.LIRFrameState; |
30 import org.graalvm.compiler.lir.LIRFrameState; |
33 import org.graalvm.compiler.lir.amd64.AMD64Call; |
31 import org.graalvm.compiler.lir.amd64.AMD64Call; |
34 import org.graalvm.compiler.lir.gen.LIRGeneratorTool; |
32 import org.graalvm.compiler.lir.gen.LIRGeneratorTool; |
39 import org.graalvm.compiler.nodes.IndirectCallTargetNode; |
37 import org.graalvm.compiler.nodes.IndirectCallTargetNode; |
40 import org.graalvm.compiler.nodes.StructuredGraph; |
38 import org.graalvm.compiler.nodes.StructuredGraph; |
41 import org.graalvm.compiler.nodes.ValueNode; |
39 import org.graalvm.compiler.nodes.ValueNode; |
42 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode; |
40 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode; |
43 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op; |
41 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op; |
44 import org.graalvm.compiler.nodes.cfg.Block; |
|
45 import org.graalvm.compiler.options.Option; |
|
46 import org.graalvm.compiler.options.OptionKey; |
|
47 import org.graalvm.compiler.options.OptionType; |
|
48 import org.graalvm.compiler.options.OptionValues; |
|
49 |
42 |
50 import jdk.vm.ci.amd64.AMD64; |
43 import jdk.vm.ci.amd64.AMD64; |
51 import jdk.vm.ci.meta.AllocatableValue; |
44 import jdk.vm.ci.meta.AllocatableValue; |
52 import jdk.vm.ci.meta.Value; |
45 import jdk.vm.ci.meta.Value; |
53 |
46 |
54 public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder { |
47 public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder { |
55 |
|
56 public static class Options { |
|
57 // @formatter:off |
|
58 @Option(help = "AMD64: Emit lfence instructions at the beginning of basic blocks", type = OptionType.Expert) |
|
59 public static final OptionKey<Boolean> MitigateSpeculativeExecutionAttacks = new OptionKey<>(false); |
|
60 // @formatter:on |
|
61 } |
|
62 |
48 |
63 public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) { |
49 public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) { |
64 super(graph, gen, nodeMatchRules); |
50 super(graph, gen, nodeMatchRules); |
65 } |
51 } |
66 |
52 |
135 |
121 |
136 @Override |
122 @Override |
137 public AMD64LIRGenerator getLIRGeneratorTool() { |
123 public AMD64LIRGenerator getLIRGeneratorTool() { |
138 return (AMD64LIRGenerator) gen; |
124 return (AMD64LIRGenerator) gen; |
139 } |
125 } |
140 |
|
141 @Override |
|
142 public void doBlockPrologue(Block block, OptionValues options) { |
|
143 if (MitigateSpeculativeExecutionAttacks.getValue(options)) { |
|
144 boolean hasControlSplitPredecessor = false; |
|
145 for (Block b : block.getPredecessors()) { |
|
146 if (b.getSuccessorCount() > 1) { |
|
147 hasControlSplitPredecessor = true; |
|
148 break; |
|
149 } |
|
150 } |
|
151 boolean isStartBlock = block.getPredecessorCount() == 0; |
|
152 if (hasControlSplitPredecessor || isStartBlock) { |
|
153 getLIRGeneratorTool().emitLFence(); |
|
154 } |
|
155 } |
|
156 } |
|
157 } |
126 } |