[turbofan,arm64] Add float loads poisoning.

Also extend load poisoning testing for arm and arm64.

This is a port of I1ef202296744a39054366f2bc424d6952c3bbe9d,
originally introduced for arm.

Change-Id: I7d317bba6be633dd1e563daa7231d3c5e930f8e4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1691032
Commit-Queue: Martyn Capewell <martyn.capewell@arm.com>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63519}
This commit is contained in:
Artem Serov 2019-07-25 18:35:08 +01:00 committed by Commit Bot
parent ffffed9020
commit 2869d9de0d
3 changed files with 123 additions and 5 deletions

View File

@ -389,6 +389,36 @@ void EmitWordLoadPoisoningIfNeeded(
}
}
void EmitMaybePoisonedFPLoad(CodeGenerator* codegen, InstructionCode opcode,
Arm64OperandConverter* i, VRegister output_reg) {
const MemoryAccessMode access_mode =
static_cast<MemoryAccessMode>(MiscField::decode(opcode));
AddressingMode address_mode = AddressingModeField::decode(opcode);
if (access_mode == kMemoryAccessPoisoned && address_mode != kMode_Root) {
UseScratchRegisterScope temps(codegen->tasm());
Register address = temps.AcquireX();
switch (address_mode) {
case kMode_MRI: // Fall through.
case kMode_MRR:
codegen->tasm()->Add(address, i->InputRegister(0), i->InputOperand(1));
break;
case kMode_Operand2_R_LSL_I:
codegen->tasm()->Add(address, i->InputRegister(0),
i->InputOperand2_64(1));
break;
default:
// Note: we don't need poisoning for kMode_Root loads as those loads
// target a fixed offset from root register which is set once when
// initializing the vm.
UNREACHABLE();
}
codegen->tasm()->And(address, address, Operand(kSpeculationPoisonRegister));
codegen->tasm()->Ldr(output_reg, MemOperand(address));
} else {
codegen->tasm()->Ldr(output_reg, i->MemoryOperand());
}
}
} // namespace
#define ASSEMBLE_SHIFT(asm_instr, width) \
@ -1599,13 +1629,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kArm64LdrS:
__ Ldr(i.OutputDoubleRegister().S(), i.MemoryOperand());
EmitMaybePoisonedFPLoad(this, opcode, &i, i.OutputDoubleRegister().S());
break;
case kArm64StrS:
__ Str(i.InputFloat32OrZeroRegister(0), i.MemoryOperand(1));
break;
case kArm64LdrD:
__ Ldr(i.OutputDoubleRegister(), i.MemoryOperand());
EmitMaybePoisonedFPLoad(this, opcode, &i, i.OutputDoubleRegister());
break;
case kArm64StrD:
__ Str(i.InputFloat64OrZeroRegister(0), i.MemoryOperand(1));

View File

@ -101,7 +101,7 @@ TEST(DisasmPoisonPolymorphicLoad) {
"csdb", // spec. barrier
"ldr <<BSt:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load backing store
"and <<BSt>>, <<BSt>>, " + kPReg, // apply the poison
"ldr <<Prop:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load the property
"ldr <<Prop:r[0-9]+>>, \\[<<BSt>>, #\\+[0-9]+\\]", // load the property
"and <<Prop>>, <<Prop>>, " + kPReg, // apply the poison
// Ldone:
};
@ -109,5 +109,42 @@ TEST(DisasmPoisonPolymorphicLoad) {
#endif // ENABLE_DISASSEMBLER
}
TEST(DisasmPoisonMonomorphicLoadFloat64) {
#ifdef ENABLE_DISASSEMBLER
if (i::FLAG_always_opt || !i::FLAG_opt) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_untrusted_code_mitigations = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
CompileRun(
"function mono(o) { return o.x; }"
"%PrepareFunctionForOptimization(mono);"
"mono({ x : 1.1 });"
"mono({ x : 1.1 });"
"%OptimizeFunctionOnNextCall(mono);"
"mono({ x : 1.1 });");
// Matches that the property access sequence is instrumented with
// poisoning.
std::vector<std::string> patterns_array = {
"ldr <<Map:r[0-9]+>>, \\[<<Obj:r[0-9]+>>, #-1\\]", // load map
"ldr <<ExpMap:r[0-9]+>>, \\[pc, #", // load expected map
"cmp <<Map>>, <<ExpMap>>", // compare maps
"bne", // deopt if different
"eorne " + kPReg + ", " + kPReg + ", " + kPReg, // update the poison
"csdb", // spec. barrier
"ldr <<Field:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load the field
"mov <<Mov:r[0-9]+>>, #[0-9]+", // addr. calculation
"add ip, <<Field>>, <<Mov>>", // addr. calculation
"and ip, ip, " + kPReg, // apply the poison
"vldr d[0-9]+, \\[ip", // load Float64
};
CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array));
#endif // ENABLE_DISASSEMBLER
}
} // namespace internal
} // namespace v8

View File

@ -49,8 +49,8 @@ TEST(DisasmPoisonMonomorphicLoad) {
"b.ne", // deopt if different
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"ldursw x<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field
"and x<<Field>>, x<<Field>>, " + kPReg, // apply the poison
"ldursw <<Field:x[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field
"and <<Field>>, <<Field>>, " + kPReg, // apply the poison
};
#else
std::vector<std::string> patterns_array = {
@ -153,5 +153,56 @@ TEST(DisasmPoisonPolymorphicLoad) {
#endif // ENABLE_DISASSEMBLER
}
TEST(DisasmPoisonMonomorphicLoadFloat64) {
#ifdef ENABLE_DISASSEMBLER
if (i::FLAG_always_opt || !i::FLAG_opt) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_untrusted_code_mitigations = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
CompileRun(
"function mono(o) { return o.x; }"
"%PrepareFunctionForOptimization(mono);"
"mono({ x : 1.1 });"
"mono({ x : 1.1 });"
"%OptimizeFunctionOnNextCall(mono);"
"mono({ x : 1.1 });");
// Matches that the property access sequence is instrumented with
// poisoning.
#if defined(V8_COMPRESS_POINTERS)
std::vector<std::string> patterns_array = {
"ldur <<Map:w[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map
"ldr <<ExpMap:w[0-9]+>>, pc", // load expected map
"cmp <<Map>>, <<ExpMap>>", // compare maps
"b.ne", // deopt if differ
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"ldursw <<F1:x[0-9]+>>, \\[<<Obj>>, #11\\]", // load field
"add <<F1>>, x26, <<F1>>", // Decompress ref
"add <<Addr:x[0-9]+>>, <<F1>>, #0x[0-9a-f]+", // addr. calculation
"and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison
"ldr d[0-9]+, \\[<<Addr>>\\]", // load Float64
};
#else
std::vector<std::string> patterns_array = {
"ldur <<Map:x[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map
"ldr <<ExpMap:x[0-9]+>>, pc", // load expected map
"cmp <<Map>>, <<ExpMap>>", // compare maps
"b.ne", // deopt if differ
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
"csdb", // spec. barrier
"add <<Addr:x[0-9]+>>, <<Obj>>, #0x[0-9a-f]+", // addr. calculation
"and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison
"ldr d[0-9]+, \\[<<Addr>>\\]", // load Float64
};
#endif
CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array));
#endif // ENABLE_DISASSEMBLER
}
} // namespace internal
} // namespace v8