Cranelift AArch64: Harden the Spectre mitigations (#4555)

Use the `CSDB` instruction following Arm's recommendation.

Copyright (c) 2022, Arm Limited.
This commit is contained in:
Anton Kirilov
2022-08-01 18:20:48 +01:00
committed by GitHub
parent 893fadb485
commit a47a82d2e5
8 changed files with 42 additions and 20 deletions

View File

@@ -280,6 +280,9 @@
;; ish". This instruction is sequentially consistent. ;; ish". This instruction is sequentially consistent.
(Fence) (Fence)
;; Consumption of speculative data barrier.
(Csdb)
;; FPU move. Note that this is distinct from a vector-register ;; FPU move. Note that this is distinct from a vector-register
;; move; moving just 64 bits seems to be significantly faster. ;; move; moving just 64 bits seems to be significantly faster.
(FpuMove64 (FpuMove64

View File

@@ -1656,6 +1656,9 @@ impl MachInstEmit for Inst {
&Inst::Fence {} => { &Inst::Fence {} => {
sink.put4(enc_dmb_ish()); // dmb ish sink.put4(enc_dmb_ish()); // dmb ish
} }
&Inst::Csdb {} => {
sink.put4(0xd503229f);
}
&Inst::FpuMove64 { rd, rn } => { &Inst::FpuMove64 { rd, rn } => {
let rd = allocs.next_writable(rd); let rd = allocs.next_writable(rd);
let rn = allocs.next(rn); let rn = allocs.next(rn);
@@ -2910,6 +2913,8 @@ impl MachInstEmit for Inst {
rm: ridx, rm: ridx,
}; };
inst.emit(&[], sink, emit_info, state); inst.emit(&[], sink, emit_info, state);
// Prevent any data value speculation.
Inst::Csdb.emit(&[], sink, emit_info, state);
// Load address of jump table // Load address of jump table
let inst = Inst::Adr { rd: rtmp1, off: 16 }; let inst = Inst::Adr { rd: rtmp1, off: 16 };

View File

@@ -40,6 +40,7 @@ fn test_aarch64_binemit() {
insns.push((Inst::Ret { rets: vec![] }, "C0035FD6", "ret")); insns.push((Inst::Ret { rets: vec![] }, "C0035FD6", "ret"));
insns.push((Inst::Nop0, "", "nop-zero-len")); insns.push((Inst::Nop0, "", "nop-zero-len"));
insns.push((Inst::Nop4, "1F2003D5", "nop")); insns.push((Inst::Nop4, "1F2003D5", "nop"));
insns.push((Inst::Csdb, "9F2203D5", "csdb"));
insns.push(( insns.push((
Inst::Udf { Inst::Udf {
use_allocated_encoding: false, use_allocated_encoding: false,

View File

@@ -703,7 +703,7 @@ fn aarch64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
collector.reg_use(rn); collector.reg_use(rn);
collector.reg_use(rt); collector.reg_use(rt);
} }
&Inst::Fence {} => {} &Inst::Fence {} | &Inst::Csdb {} => {}
&Inst::FpuMove64 { rd, rn } => { &Inst::FpuMove64 { rd, rn } => {
collector.reg_def(rd); collector.reg_def(rd);
collector.reg_use(rn); collector.reg_use(rn);
@@ -1679,6 +1679,9 @@ impl Inst {
&Inst::Fence {} => { &Inst::Fence {} => {
format!("dmb ish") format!("dmb ish")
} }
&Inst::Csdb {} => {
format!("csdb")
}
&Inst::FpuMove64 { rd, rn } => { &Inst::FpuMove64 { rd, rn } => {
let rd = pretty_print_vreg_scalar(rd.to_reg(), ScalarSize::Size64, allocs); let rd = pretty_print_vreg_scalar(rd.to_reg(), ScalarSize::Size64, allocs);
let rn = pretty_print_vreg_scalar(rn, ScalarSize::Size64, allocs); let rn = pretty_print_vreg_scalar(rn, ScalarSize::Size64, allocs);
@@ -2545,6 +2548,8 @@ impl Inst {
format!( format!(
concat!( concat!(
"b.hs {} ; ", "b.hs {} ; ",
"csel {}, xzr, {}, hs ; ",
"csdb ; ",
"adr {}, pc+16 ; ", "adr {}, pc+16 ; ",
"ldrsw {}, [{}, {}, LSL 2] ; ", "ldrsw {}, [{}, {}, LSL 2] ; ",
"add {}, {}, {} ; ", "add {}, {}, {} ; ",
@@ -2552,10 +2557,12 @@ impl Inst {
"jt_entries {:?}" "jt_entries {:?}"
), ),
default_target, default_target,
rtmp2,
ridx,
rtmp1, rtmp1,
rtmp2, rtmp2,
rtmp1, rtmp1,
ridx, rtmp2,
rtmp1, rtmp1,
rtmp1, rtmp1,
rtmp2, rtmp2,

View File

@@ -375,6 +375,10 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
op, ty op, ty
))); )));
} }
if op == Opcode::SelectifSpectreGuard {
ctx.emit(Inst::Csdb);
}
} }
Opcode::Bitselect | Opcode::Vselect => implemented_in_isle(ctx), Opcode::Bitselect | Opcode::Vselect => implemented_in_isle(ctx),

View File

@@ -358,25 +358,26 @@ mod test {
let code = result.buffer.data(); let code = result.buffer.data();
// 0: 7100081f cmp w0, #0x2 // 0: 7100081f cmp w0, #0x2
// 4: 54000102 b.cs 0x24 // b.hs, b.nlast // 4: 54000122 b.cs 0x28 // b.hs, b.nlast
// 8: 9a8023e9 csel x9, xzr, x0, cs // cs = hs, nlast // 8: 9a8023e9 csel x9, xzr, x0, cs // cs = hs, nlast
// c: 10000088 adr x8, 0x1c // c: d503229f csdb
// 10: b8a95909 ldrsw x9, [x8, w9, uxtw #2] // 10: 10000088 adr x8, 0x1c
// 14: 8b090108 add x8, x8, x9 // 14: b8a95909 ldrsw x9, [x8, w9, uxtw #2]
// 18: d61f0100 br x8 // 18: 8b090108 add x8, x8, x9
// 1c: 00000010 udf #16 // 1c: d61f0100 br x8
// 20: 00000018 udf #24 // 20: 00000010 udf #16
// 24: d2800060 mov x0, #0x3 // #3 // 24: 00000018 udf #24
// 28: d65f03c0 ret // 28: d2800060 mov x0, #0x3 // #3
// 2c: d2800020 mov x0, #0x1 // #1 // 2c: d65f03c0 ret
// 30: d65f03c0 ret // 30: d2800020 mov x0, #0x1 // #1
// 34: d2800040 mov x0, #0x2 // #2 // 34: d65f03c0 ret
// 38: d65f03c0 ret // 38: d2800040 mov x0, #0x2 // #2
// 3c: d65f03c0 ret
let golden = vec![ let golden = vec![
31, 8, 0, 113, 2, 1, 0, 84, 233, 35, 128, 154, 136, 0, 0, 16, 9, 89, 169, 184, 8, 1, 9, 31, 8, 0, 113, 34, 1, 0, 84, 233, 35, 128, 154, 159, 34, 3, 213, 136, 0, 0, 16, 9, 89,
139, 0, 1, 31, 214, 16, 0, 0, 0, 24, 0, 0, 0, 96, 0, 128, 210, 192, 3, 95, 214, 32, 0, 169, 184, 8, 1, 9, 139, 0, 1, 31, 214, 16, 0, 0, 0, 24, 0, 0, 0, 96, 0, 128, 210, 192,
128, 210, 192, 3, 95, 214, 64, 0, 128, 210, 192, 3, 95, 214, 3, 95, 214, 32, 0, 128, 210, 192, 3, 95, 214, 64, 0, 128, 210, 192, 3, 95, 214,
]; ];
assert_eq!(code, &golden[..]); assert_eq!(code, &golden[..]);

View File

@@ -24,6 +24,7 @@ block0(v0: i64, v1: i32):
; subs xzr, x10, x11 ; subs xzr, x10, x11
; movz x14, #0 ; movz x14, #0
; csel x0, x14, x13, hi ; csel x0, x14, x13, hi
; csdb
; ret ; ret
; block2: ; block2:
; udf #0xc11f ; udf #0xc11f
@@ -46,7 +47,7 @@ block0(v0: i64, v1: i32):
; subs xzr, x8, #65536 ; subs xzr, x8, #65536
; movz x11, #0 ; movz x11, #0
; csel x0, x11, x10, hi ; csel x0, x11, x10, hi
; csdb
; ret ; ret
; block2: ; block2:
; udf #0xc11f ; udf #0xc11f

View File

@@ -32,7 +32,7 @@ block5(v5: i32):
; block0: ; block0:
; emit_island 36 ; emit_island 36
; subs wzr, w0, #3 ; subs wzr, w0, #3
; b.hs label1 ; adr x15, pc+16 ; ldrsw x1, [x15, x0, LSL 2] ; add x15, x15, x1 ; br x15 ; jt_entries [Label(MachLabel(3)), Label(MachLabel(5)), Label(MachLabel(7))] ; b.hs label1 ; csel x1, xzr, x0, hs ; csdb ; adr x15, pc+16 ; ldrsw x1, [x15, x1, LSL 2] ; add x15, x15, x1 ; br x15 ; jt_entries [Label(MachLabel(3)), Label(MachLabel(5)), Label(MachLabel(7))]
; block1: ; block1:
; movz x5, #4 ; movz x5, #4
; b label2 ; b label2